3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Re-ducksパターンのSelectorで引数を使う

Posted at

概要

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;

参考

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?