在重选功能体内使用组件道具?

时间:2019-03-13 14:40:07

标签: reactjs redux react-redux reselect

老实说,经过数小时的研究,我完全不理解重新选择,所以我只想问问为什么需要它,以及它是否可以帮助您。

  

选择器很有效。除非更改其中一个参数,否则不会重新计算选择器。

有点不清楚,我们在这里是argument是什么意思,但我认为不是redux状态,因为否则重新选择就没有意义了。

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

第一个问题是,例如,如果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) });

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

2 个答案:

答案 0 :(得分:1)

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

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

关于阐明重新选择的用例: 它会重新计算状态或道具是否发生变化(确实存在任何论点)。那么为什么要使用它呢?我使用它有两个原因

  1. 您可以组合来自多个reducer的部分状态,并构建我们称为“ meta-reducer”的状态并将其传递给您的组件。这样,您可以将代码仅放在一个位置(选择器),并且可以在不同组件之间重用它。想象每个reducer像一个数据库表,而选择器像一个查询结果。您可以查询状态中的任何内容,并希望保留结果以提高性能。
  2. 与其在每次组件呈现时运行的mapStateToProps上运行此逻辑(无论状态是否更改),都不会在每次状态更改时运行1次,并且在以下情况下获得缓存的版本:组件重新渲染。例如,如果子组件仅由于其父组件被渲染而与其选择器相关的状态部分未改变而进行渲染,则会发生这种情况。因此,我喜欢一直使用选择器,而不是直接访问redux状态。

答案 1 :(得分:0)

这是典型的流程。

您将有一些ConnectedComponent挂接到connect上,它的mapStateToProps会同时调用stateownProps的选择器。

对于从id中获取props和从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>
)