web-dev-qa-db-ja.com

reduxでreselectを使用してownPropsを取得するにはどうすればよいですか?

ownPropsの一部のmapStateToPropsに基づくreselectを使用して、メモ化されたセレクターを作成したいと思います。

19

これを行うには、 react-redux によって提供されるconnectメソッドを使用してセレクターをコンポーネントに接続し、コンポーネントのプロパティ(ownProps)を2番目の引数としてセレクターに渡します。

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関数を取得します。コンテナのレンダリング順序に関係なく、メモ化が正しく機能するようになりました。


これは適応されました(露骨にコピーされました)ドキュメントを再選択

25
Seth