在重新选择的函数体内使用组件道具?

Using component prop inside function body of reselect?

老实说,经过几个小时的研究,我完全不明白 reselect,所以我只是问我为什么需要它,以及它是否有帮助。

Selectors are efficient. A selector is not recomputed unless one of its arguments changes.

有点不清楚,我们这里的argument是什么意思,但我假设不是redux状态,否则reselect就没有意义了。

我的目标是每次发生事情时不计算整个列表,因为它可以包含数千个元素。

第一个问题是,如果例如 state["2"] 的值更改为 4,它会 运行 遍历整个列表?

//for an example, in the next list, the key is the child,
//and the value is it's parent
const state = {
  1: 5,
  2: 5,
  3: 2,
  4: 1,
  5: 10,
  //...
  1000: 342
};

//and we have to find all children of a specific element,
//what we get from the component's own props

const getState = (
  state,
  props //okay, I can access it here
) => state;

const getChildren = createSelector(
  [getState],
  state => Object.keys(state).filter(child => {
    const parent = state[child];

    return parent === props.id //but I need it here
  })
);

const mapStateToProps = (state, props) = ({ children: getChildren(state, props) });

还有主要问题:如何访问函数体内的道具?

您可以将 props 参数直接传递给另一个选择器 getChildren 而您不需要像这样的第一个 getState:

const getChildren = createSelector(
   [
      state => state,
      props => props
   ], (state, props) => {...}

关于澄清重新选择的用例: 如果状态或道具发生变化(确实是任何参数),它 重新计算。那么为什么要使用它呢?我使用它有两个原因

  1. 您可以组合来自多个 reducer 的部分状态,构建我们称之为 'meta-reducer' 的内容,并将其传递给您的组件。通过这种方式,您只需将该代码放在一个地方(选择器),您就可以在不同的组件中重用它。想象一下每个 reducer 就像一个数据库 table 而 selector 就像一个查询结果。您可以从您的状态查询任何内容,并且您希望将结果缓存起来以提高性能。
  2. 而不是 运行 在 mapStateToProps 上 运行 每次组件呈现时都 运行 逻辑,你 运行 每次状态更改仅 1 次,如果组件重新呈现,您将获得缓存版本。例如,如果子组件渲染只是因为其父组件渲染但与其选择器相关的状态部分没有改变,就会发生这种情况。所以我喜欢一直使用选择器而不是直接访问 redux 状态。

这是典型的流程。

您将有一些 ConnectedComponent 挂接到 connect,并且它的 mapStateToProps 调用带有 stateownProps 的选择器。

对于从 props 获取 id 和从 state.

获取对象,您都有单独的选择器

使用 ConnectedComponent

<span>
    <ConnectedComponent id="123" />
</span>

mapStateToProps (ConnectedComponent)

import {connect} from 'react-redux'
import {getMyObjectSelector} from './selectors';

const mapStateToProps = (state, ownProps) => ({
    myObject: getMyObjectSelector(state, ownProps)
});

export default connect(mapStateToProps)(Component)

选择器

const getIdFromProps = (state, props) => props.id
const getMyObjectsFromState= state => state.myObjects;

export getMyObjectSelector = createSelector(
   getMyObjectsFromState,
   getIdFromProps,
   (objects, id) => objects[id]
);

组件

export const Component = ({myObject}) => (
   <span>
   // Do stuff
   </span>
)