概要
React ReduxのRe-ducksパターンにおいて、Selectorで引数を使う方法です。
サンプルとか見てても引数を使わない簡単な方法での実装例が多く、少し戸惑ったので書いていこうと思います。
どんな時に使うかというと、API等から直接データをStoreに入れてデータを扱いたい場合などに使えるかなと思います。
Selectorでは reselect
を使う前提で書いていきます。
方法
毎回 createSelectorする方法
createSelector
を関数の中に内包して、毎回発行する方法です。
以下のように、createSelector
で作成したインスタンスをreturn
する関数を作ります。
簡単にできますが、毎回createSelectorを呼び出して関数を作成しているので、パフォーマンスが悪そうな感じがします。
reducks/subjects/selectors.js
import { createSelector } from "reselect";
export const getChildSubject = (state, subjectName) => {
return createSelector(
(state) => state.subjects,
(subjects) => {
if (subjectName in subjects) {
return subjects[subjectName].value;
}
}
)(state);
}
components/sample.jsx
import React from 'react';
import { useDispatch, useSelector } from "react-redux";
import { getChildSubject } from "../../reducks/subjects/operations";
const Sample = (props) => {
const dispatch = useDispatch();
const selector = useSelector(state => state);
const childValue = getChildSubject(selector, "subjectName");
return (
<div>{childValue}</div>
)
};
export default Sample;
Memoizeを使用する方法
lodash.memoize
モジュールを使用することで、引数をcreateSelector
内で使用できるようになります。
reselectの利用方法に沿った形になるため、こちらの方が安全にしようできるかなという印象です。
createSelector
内でmemoize
関数内にfunctionで記述します。
引数は複数設定しても問題ありません。
yarn add lodash.memoize
reducks/subjects/selectors.js
import { createSelector } from "reselect";
import memoize from 'lodash.memoize';
export const getChildSubject = createSelector(
(state) => state.subjects,
(subjects) => memoize((subjectName) => {
if (subjectName in subjects) {
return subjects[subjectName].value;
}
})
);
components/sample.jsx
import React from 'react';
import { useDispatch, useSelector } from "react-redux";
import { getChildSubject } from "../../reducks/subjects/operations";
const Sample = (props) => {
const dispatch = useDispatch();
const selector = useSelector(state => state);
const childSubjectSelector = getChildSubject(selector);
const childValue = childSubjectSelector("subjectName");
return (
<div>{childValue}</div>
)
};
export default Sample;