LoginSignup
13
18

More than 5 years have passed since last update.

reduxでの大きなreducerの分割方法について

Last updated at Posted at 2015-12-28

今回は前回のreduxでのstate管理についてで記述した
1つのIdに紐づくstateが大量に作成された結果、巨大なaction,reducerファイルができてしまった
という問題をどのように解決したかについてまとめていきたいと思います。

前回も記述しましたが実際にredux使ってみると小さなaction,reducerファイルと一つのIdに紐づく大きなaction,reducerができました。その解決策は至ってシンプルなものでした。stateを分割しそれぞれに同じIdを振っただけです。

下のような形です。こんな感じのstateを

unitState = {
    id:"testId",
    stateA:{
        aaa,
        bbb,
        (以下略)
    },
    stateB:{
        ccc,
        ddd,
        (以下略)
    },
    (以下略)
}

下のように分割しました。

stateA = {
        id:"testId",
        aaa,
        bbb,    
        (以下略)
} 

stateB = {
        id:"testId",
        ccc,
        ddd,
        (以下略)
    },
(以下略)

stateA,stateBなどなど全部reducerファイルを持つわけですが、それに全部追加用と削除用のcaseを追加しました。

reducerStateA.js
// stateADefinitionはstateAの定義ファイル
import stateADefinition from "stateADefinition";

export default function stateA(state = initialState.stateA, action) {
    switch (action.type) {
        case ActionTypes.ADD_UNIT:
            // 追加処理
            return Object.assign({}, state, { [action.id]: stateADefinition[unitType] });
        case ActionTypes.DELETE_UNIT:
            // 削除処理
            let tempObj = Object.assign({}, state);
            delete tempObj[action.id];
            return tempObj;

        (他の処理は略)
        default:
            return state;
    }
};
reducerStateB.js
import stateADefinition from "stateBDefinition";
import * as Immutable from "immutable";

export default function stateB(state = initialState.stateB, action) {
    switch (action.type) {
        case ActionTypes.ADD_UNIT:
            // 追加処理は略
        case ActionTypes.DELETE_UNIT:
            // 削除処理は略

        (他の処理は略)
        default:
            return state;
    }
};

actionは下のような形になります。

action.js
// ひたすらActionTypesが定義されている
import ActionTypes from 'ActionTypes';

function addUnit(id,unitType){
    return {
        type:ActionTypes.ADD_UNIT,
        id,
        unitType
    }
}

function deleteUnit(id){
    return {
        type:ActionTypes.DELETE_UNIT,
        id
    }
}

dispatchされたactionは全てのreducerファイルに届くので、追加 or 削除したい際は好きなファイルでaddUnitかdeleteUnitを呼ぶだけでOKでした。オブザーバーパターンとか考える必要すらなかったです。
ちなみに必要ないかもしれないですがstateADefinitionはこんな感じのファイルです。

stateADefinition.js
const definition = {
    squareType:{
            aaa:"A1",
            bbb:"B1",
            ()
          },
    circleType:{
            aaa:"A2",
            bbb:"B2",
            ()
        },
    ()
};
export default definition;

各unitのstateの定義が設定されています。actionでidと一緒に渡したunitのtypeを使ってunitの定義を取得します。皆が自由に新しいunitの定義を追加できます。
新規にstateを追加したい際も同様にreducerとdefinitionファイルを追加するだけです。拡張性がreduxの売りだと聞きましたが、確かにその通りかなと思いました。

さらに言えばreduxについて良くしらなくても定義ファイルの追加、変更はできます。少し話はずれますがaction,reducerも単なる関数なので結構簡単にテストが書けます。仕事の分割が非常にやりやすいなというのが開発をしていての現実的な感想です。

13
18
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
13
18