Как я могу получить ownProps, используя reselect на redux?

Я хочу создать селектор с memoization, используя reselect на основе некоторых ownProps of mapStateToProps.

1 ответов


вы можете сделать это, подключив селектор к компоненту с помощью connect метод react-redux, затем передача реквизита компонента (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;

, это не memoize правильно, если у вас есть несколько экземпляров компонента, из которого вы передаете реквизит. В этом случае селектор получит другое props аргумент каждый раз, поэтому он всегда будет пересчитывать вместо возврата кэшированного значения.

для совместного использования селектора между несколькими компонентами при передаче реквизита и сохраняя memoization, каждый экземпляр компонента нуждается в собственной частной копии селектора.

вы можете сделать это создание функции, возвращающей новую копию селектора при каждом его вызове.

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 контейнер получит свой собственный