如何使用redux上的重新选择来获得ownProps



我想在mapStateToProps的某些ownProps的基础上使用reselect创建一个具有记忆功能的选择器。

您可以使用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;

如果为连接提供的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选择器。无论容器的呈现顺序如何,记忆化现在都能正常工作。


这是改编自Reselect文档

(公然复制)

最新更新