ownProps
の一部のmapStateToProps
に基づくreselectを使用して、メモ化されたセレクターを作成したいと思います。
これを行うには、 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
関数を取得します。コンテナのレンダリング順序に関係なく、メモ化が正しく機能するようになりました。
これは適応されました(露骨にコピーされました)ドキュメントを再選択