Redux Toolkit入門

4 min read読了の目安(約3800字

はじめに

フロントエンド開発の状態管理ライブラリとして有名なのがReduxです。このReduxによってどの階層からでも状態を更新、参照する事ができます。

しかーーし!!

このReduxを導入したい場合、複数ファイルに渡って記述する必要があるため、ややこしいなぁと初めは苦手に感じる人も多いと思います。僕自身もそうでした。
そんな、みんなの苦痛に応えるかのように現れたのがRedux Toolkitです。これはReduxと同じ機能を実現でき、更にもっと簡単に実装できるというぐぅ有能なライブラリです。
そこで今回は、Reduxが苦手なあなたと自分のRedux Toolkitへの理解を改めて深めるために、Redux Toolkitの実装を確認していきます。

実装

プロジェクト作成・ライブラリ導入・起動

以下のコマンドからTypescriptで記述されたReactのテンプレートを作成致します。
Redux Toolkitのテンプレートを作っても良かったのですが、今回はプロジェクトを進めていく中でRedux Toolkitを使いたいというユースケースを想定しReactにRedu Toolkitを導入する手順を示していきたいと思います。

npx create-react-app <プロジェクト名> --template typescript
cd <プロジェクト名>
yarn add @reduxjs/toolkit react-redux // 今回の肝となるライブラリ
yarn 
yarn start

Sliceの定義

Redux ToolkitではSliceという概念があります。ReduxではStoreに全ての状態を詰め込んで管理していたのですが、Redux ToolkitではSliceを用いる事でSliceごとにStore、Reducer、Actionを管理する事が出来るようになりました。恐らく、これがみんなの心を震わせている点だと思います。例えるならば、Reduxでは家族全員の情報をまとめて管理して、Redux Toolkitではお父さん、お母さん、子供など、家族の中でも分けて状態を管理している感じです。
分かり易かったらいいねを是非お願い致します。

generation.ts
import { createSlice } from '@reduxjs/toolkit';
import { RootState } from '../app/store';
 
 
 type Generation = {
  generation: string
}

const initialState: Generation = {
  generation: 'First'
}
 
export const generationSlice = createSlice({
  name: 'generation',
  initialState,
  reducers: {
    changeGeneration: (state, action) => {
      state.generation = action.payload;
    },
  },
})

export const { changeGeneration } = generationSlice.actions;

export const selectGeneration = (state: RootState) => 
  state.generationReducer.generation
  
export default generationSlice.reducer

Storeの定義(Sliceをまとめる)

configureStoreを使用して、作成したSliceを1つにまとめstoreに入れます。
Rootstateに複数にReducerをまとめた場合の、最終的なStateの型を渡しています。

store.ts
import { configureStore } from '@reduxjs/toolkit';

import generationReducer from '../store/generation';

export const store = configureStore({
    reducer: {
        generationReducer: generationReducer,
    },
});

export type RootState = ReturnType<typeof store.getState>;

AppにStoreを渡す

最後にAppコンポーネントにconfigureStoreを用いて作成したstoreを渡すことによってどこからでもStoreにアクセス出来るようになりました。

App.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { store } from './app/store';
import { Provider } from 'react-redux';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

状態の更新

それでは実際に状態を更新していきましょう。
今回は、Buttonを押すとgenerationというStateが切り替わるように致します。
useSelectorでgenerationのStateを参照できます。また、dispatchで任意のActionを発火させる事でStateを切り替えています。

index.tsx
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { selectGeneration, changeGeneration } from "../store/generation";

const GenerationPage: React.VFC = () => {
  const generation = useSelector(selectGeneration);
  const dispatch = useDispatch();
  return (
    <div>
      <button type="button" onClick={() => dispatch(changeGeneration("First"))}>
        First Generation
      </button>
      <button
        type="button"
        onClick={() => dispatch(changeGeneration("Second"))}
      >
        Second Generation
      </button>
      <div>Generation is {generation}</div>
    </div>
  );
};

export default GenerationPage;

上記の通りに実装すると、以下のようにButtonを押した際にStateを切り替える事ができます。

まとめ

いかがだったでしょうか?
読んでくださった方のReduxへのハードルが少しでも低くなれば幸いです。
改めて、Redux Toolkitだけでなく、Reduxの勉強(特に、基本的な考え)をしてみるともっと理解が深まると思うので是非やってみて下さい!
当たり前のことかもしれませんが、簡単に目的の機能を実装できるライブラリばかりに目を向けずに、なぜそういったライブラリが生まれたのか、なんの課題を解決しようとしているのか、根本となっている考え方は何なのか、といった事も考えられるようにこれからも頑張っていきたいです!!
たくさんのご指摘、ご質問お待ちしております!!!