LoginSignup
11
6

More than 3 years have passed since last update.

ReduxのReducerでのState操作の基本

Posted at

目次

概要

この記事では、Reduxを使用したときのStoreにあるStateをReducerで操作する際の基本として、主にCRUDアプリケーションをはじめとした非常に多くの場面で利用される「追加、更新、削除」についてまとめています。
ReducerでのState操作の方法が分からなくなった時にこの記事を参考にしていただけるようであれば幸いです。
なおこの記事では、Reactを使用していることを前提としています。

前提知識

  • Reduxの基本的な知識を身につけている(Reduxの基本についてはこちらの記事にまとめています)
  • JavaScript(ES2015以降)で使用できる構文をある程度知っている

環境

導入ライブラリ version
React 16.13.1
react-redux 7.2.0
redux 4.0.5
lodash 4.17.15

ReducerでState操作

State操作の掟

Reduxで扱うStateはすべて、Storeというところに格納されています。
そしてそのStoreに格納されているStateは直接変更してはいけません。(イミュータブル)
ではStateを変更したい場合にはどのようにStateを変更すればいいのか以下に操作例をまとめます。

Stateの操作例

配列のState操作

悪い例

// Reducer
export default (state=[], action) => {
  switch(action.type){
    // 追加する場合
    case 'ADD':
      return state.push('hi');
    // 更新する場合
    case 'REPLACE':
      return state[0] = 'bye';
    // 削除する場合
    case 'REMOVE':
      return state.pop();
    default:
      return state;
  };
};

この場合、エラーとなるかあるいは正しくStateが変更されません。

正しい例

// Reducer
export default (state=[], action) => {
  switch(action.type){
    // 追加する場合
    case 'ADD':
      return [...state, 'hi'];
    // 更新する場合
    case 'REPLACE':
      return state.map(element => element === 'hi' ? 'bye' : element);
    // 削除する場合
    case 'REMOVE':
      return state.filter(element => element !== 'hi');
    default:
      return state;
  };
};

このように書くことで配列のStateを正しく変更することができます。

オブジェクトのState操作

悪い例

// Reducer
export default (state={}, action) => {
  switch(action.type){
    // 追加する場合
    case 'ADD':
      return state.age = '30';
    // 更新する場合
    case 'UPDATE':
      return state.name = 'Sum';
    // 削除する場合
    case 'REMOVE':
      return delete state.name;
    default:
      return state;
  };
};

この場合、配列のときと同様にエラーとなるか正しくStateが変更されません。

正しい例

// Reducer
import _ from 'lodash';

export default (state={}, action) => {
  switch(action.type){
    // 追加する場合
    case 'ADD':
      return {...state, age: 30};
    // 更新する場合
    case 'UPDATE':
      return {...state, name: 'Sum'};
    // 削除する場合
    case 'REMOVE':
      return {...state, age: undefined};
      // または
      return _.omit(state, 'age');  // lodashを使用
    default:
      return state;
  };
};

オブジェクト構造のStateの操作はこのように記述します。

配列やオブジェクトの操作で...stateといったようにスプレッド構文を使用していることに注目しましょう。これは現在あるStateを変更するのではなく、新たに現在のStateをコピーを生成して、その中で変更を行いそれを新たにStateとしてStoreに格納していることになります。

ReduxにおけるStateのようにオブジェクトや配列などをイミュータブルに扱いたい場合にスプレッド構文が活躍します。

オブジェクトのキー補間構文

一部ではKey interpellation syntaxと呼ばれていました。
これは一体なんなのかというと、コードを見ていただいた方が早いと思うので以下で紹介します。

const countryCapital = { japan: 'Tokyo', france: 'Paris' };
const country = 'china';
const capital = 'Beijing';

{...countryCapital, [country]:capital}
// -> { japan: 'Tokyo', france: 'Paris', china: 'Beijing' }

ここで注目してもらいたいのが、{...countryCapital, [country]:capital}です。{...countryCapital}は先程説明したスプレッド構文ですが、その後に続く[country]:capitalの部分が見慣れない構文なのではないかと思います。この[country]配列ではありません。今回の場合ですと、オブジェクトのキーとしてcountryを渡していることになります。すなわち[country]:capital === china:'Beijing'ということになります。
この構文を知っていれば、ReducerのState操作を便利にしてくれるはずなので、覚えておきましょう。

まとめ

今回はReduxでのState操作の方法についてまとめました。
操作方法の例を紹介しましたが、前提として最も重要なことはStateは直接操作せずイミュータブルに扱うということです。
そのための手段としてスプレッド構文やlodashライブラリ、キー補間構文などがあるということを抑えておきましょう。

参考資料

11
6
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
11
6