我想使用基于ownProps
的{{1}} mapStateToProps
的重新选择来创建一个带备忘录的选择器。
答案 0 :(得分:25)
您可以使用react-redux提供的connect
方法将选择器连接到组件,然后将组件props(ownProps)作为第二个参数传递给选择器。
<强> container.js
强>
import { connect } from 'react-redux';
import { getVisibleTodos } from './selectors';
...
const mapStateToProps = (state, props) => {
return {
todos: getVisibleTodos(state, props),
};
};
const VisibleTodoList = connect(
mapStateToProps,
)(TodoList);
export default VisibleTodoList;
然后,您可以在选择器中访问这些道具
<强> selectors.js
强>
import { createSelector } from 'reselect';
const getVisibilityFilter = (state, props) =>
state.todoLists[props.listId].visibilityFilter;
const getTodos = (state, props) =>
state.todoLists[props.listId].todos;
const getVisibleTodos = createSelector(
...
);
export default getVisibleTodos;
然而,如果您有多个要传递道具的组件实例,则不会正确记忆。在这种情况下,选择器每次都会收到一个不同的
props
参数,因此它总是会重新计算而不是返回一个缓存的值。
要在传递道具和保留记忆时传递多个组件的选择器,组件的每个实例都需要自己的选择器私有副本。
您可以通过创建一个函数来执行此操作,该函数每次调用时都会返回选择器的新副本。
<强> selectors.js
强>
import { createSelector } from 'reselect';
const getVisibilityFilter = (state, props) =>
state.todoLists[props.listId].visibilityFilter;
const getTodos = (state, props) =>
state.todoLists[props.listId].todos;
const makeGetVisibleTodos = () => {
return createSelector(
...
);
}
export default makeGetVisibleTodos;
如果提供给connect的mapStateToProps
参数返回一个函数而不是一个对象,它将用于为容器的每个实例创建一个单独的mapStateToProps
函数。
考虑到这一点,您可以创建一个函数makeMapStateToProps
来创建一个新的getVisibleTodos
选择器,并返回一个mapStateToProps
函数,该函数具有对新选择器的独占访问权:
import { connect } from 'react-redux';
import { makeGetVisibleTodos } from './selectors';
...
const makeMapStateToProps = () => {
const getVisibleTodos = makeGetVisibleTodos();
const mapStateToProps = (state, props) => {
return {
todos: getVisibleTodos(state, props),
};
};
return mapStateToProps;
};
const VisibleTodoList = connect(
makeMapStateToProps,
)(TodoList);
export default VisibleTodoList;
现在,VisibleTodosList
容器的每个实例都将获得带有私有mapStateToProps
选择器的getVisibleTodos
函数。无论容器的渲染顺序如何,Memoization现在都能正常工作。