22

我想使用基于某些ownProps.mapStateToProps

4

1 回答 1

31

您可以通过使用react-reduxconnect提供的方法将选择器连接到组件,然后将组件道具(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在这种情况下,选择器每次都会收到不同的参数,因此它总是会重新计算而不是返回缓存值。

为了在多个组件之间共享一个选择器,同时传递 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提供给 connect 的参数返回一个函数而不是一个对象,它将用于为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获得自己的功能。无论容器的渲染顺序如何,记忆现在都可以正常工作。mapStateToPropsgetVisibleTodos


这是从重新选择文档中改编(公然复制)的

于 2016-05-24T05:22:27.020 回答