【发布时间】:2016-04-03 22:31:17
【问题描述】:
我想根据mapStateToProps 的一些ownProps 使用重新选择创建一个带有记忆功能的选择器。
【问题讨论】:
我想根据mapStateToProps 的一些ownProps 使用重新选择创建一个带有记忆功能的选择器。
【问题讨论】:
您可以通过使用react-redux 提供的connect 方法将选择器连接到组件,然后将组件道具(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 选择器。无论容器的渲染顺序如何,记忆现在都可以正常工作。
【讨论】:
getTodos 和 getVisibilityFilter 将失败。示例:betterFoobar = (id) => createSelector(foobarSelector, (foobarValue)=>id+foobarValue) 到目前为止我的想法:mapStateToProps = createStructuredSelector({ enhancedFooBar : (state, ownProps) => betterFoobar(ownProps.id)(state,ownProps)}) 但我想这不会记住。