109
71

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.

いまReduxを導入するならRedux Toolkitを使うべき

Posted at

最近 Redux Toolkit というReduxのツールがあることを知りました。
公式ドキュメントのチュートリアルを写経してみたところ、かなり良かったのでご紹介します。

Redux Toolkit とは

Redux ToolkitとはReduxをより簡潔に記述するためのツールです。

はじめはredux-starter-kitという名前で2018年から開発され、2019/10にv1.0がリリースされました。

Redux Toolkitは公式に作られたツールでReduxの公式サイトでも紹介するページがあります。

サンプルコード

Redux Toolkitを使ったコードを見てみましょう。

todosSlice
const todosSlice = createSlice({
  name: 'todos',     // ①
  initialState: [],  // ②
  reducers: {
    addTodo(state, action) {  // ③
      const { id, text } = action.payload
      state.push({ id, text, completed: false }) // ④
    }
  }
})

// ①:Sliceの名前。Action Typeのプレフィックスに使われる
// ②:Stateの初期値。Todoの配列を持つ。
// ③:Reducerの定義。Action Typeが`todos/addTodo`のAction Creatorが自動的に生成される
// ④:stateの配列にTodoのデータを追加する。

上記のコードはチュートリアルから抜粋したもので、Todoリストのデータを持つSlice1です。

Redux ToolkitではReducerを定義するとAction Creatorを自動的に生成してくれます。
Action Typeを自分で管理する必要もありません。

上記の例ではreducersに対応するObjectにaddTodoメソッド(③)があります。
この場合、addTodo()というAction Creatorが生成されます。
dispath(addTodo(payload))のように呼び出すと、addTodoメソッド(③)の内部の処理が行われます。

ちなみにReducerとAction Creatorをそれぞれ定義して書くこともできます。

ReducerとActionCreatorをそれぞれ定義した例
...
reducers: {
  addTodo: {
    reducer(state, action) {
      const { id, text } = action.payload
      state.push({ id, text, completed: false })
    },
    prepare(text, id) {
      return { payload: { text, id } }
    }
  }
}

Redux Toolkitを使うメリット

コード量が少なくなる

Redux Toolkitを使うとコード量を減らすことができるのが一番のメリットです。

サンプルコードをRedux Toolkitを使わずに書くと下のようになります。

ReduxToolkitを使わずに書いた例
// Action
const ADD_TODO = 'ADD_TODO'

const addTodo = (text, id) => ({
  type: ADD_TODO,
  id,
  text
})

// reducer
const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    default:
      return state
  }
}

前節のサンプルコードと比較すると、Actionのコードが必要なので長くなってます。
また、reducerの部分もRedux Toolkitを使ったものと比べて冗長な感じがします。

コードの可読性が高くなる

Redux ToolkitではActionとReducerが同じオブジェクト内で定義されます。
その結果、凝集度が高く可読性コードになっています。

Redux Toolkitを使わない場合、ActionとReducerのコードが違いファイルに定義されたり、同じファイル内でも離れた位置に定義されるのでコードが見づらくなります。

stateのイミュータブル性を意識しなくてよい

Redux Toolkitを使った場合、stateのイミュータブル性を気にすることなくコーディングができます。
前節のサンプルコードのreducersを見ると、pushメソッドを使ってstateに変更を加えています。

...
reducers: {
  addTodo(state, action) {
    const { id, text } = action.payload
    state.push({ id, text, completed: false }) // stateに変更を加えている
  }
}
...

Reduxのreducerでは必ずイミュータブルなstateを返す必要がありました。
もし下記の例のようにstateを直接変更して返した場合、正しく再レンダリングされないことがあります。

const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      state.push({ id, text, completed: false }) 
      return state // stateを返すと再レンダリングされない
    default:
      return state
  }
}

この仕様はバグの温床になることがありますが、Redux Toolkitを使えば安心です。

TypeScriptの型制御が効く

TypeScriptでReduxを使う場合、typesafe-actionstypescript-fsa などのツールを使っている人が多いかと思います。

Redux Toolkitを使えばそれらのツールを使わなくても型制御を効かせてReduxのコーディングができます。

Redux ToolkitのチュートリアルのコードをTypeScriptで書き直したものをこちらのCode Sandboxに作成したので触ってみてください。
特にsrc/features/todoSlice.tsを触るとstateにも型制御が効いていることがわかると思います。

最後に

Redux ToolkitはReduxを簡潔に書くことを可能にして、なおかつTypeScript対応など安全にReduxを扱うことができるようになります。

Reduxの公式サイトでもwe strongly recommend that you use it.と書いてありますし、いまReduxを導入するならRedux Toolkitを入れない理由はないと思います。

ぜひお試しを!

参考

本記事で参考にしたTodoListのソースコード

  1. Redux ToolkitではSliceという表現が出てくるのですが、Reducer/Action/Stateをひとかたまりにした概念と自分は理解しています。

109
71
1

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
109
71

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?