【React】Redux Toolkitを使って、簡単にグローバルな状態を管理する
React

【React】Redux Toolkitを使って、簡単にグローバルな状態を管理する

作成日:2022年05月26日
更新日:2022年05月26日

Redux のセッティングは難しいイメージですが、Redux Tookit を使うと、簡単にグローバルな状態を管理することができます。

手順は、ほとんど公式サイト(https://redux-toolkit.js.org/)を参考にしました。

まずは、React Redux と Redux Toolkit をインストールします。

プロジェクトのターミナルを開き、npm install @reduxjs/toolkit react-reduxを実行します。

src フォルダ内に app フォルダを作成します。

app フォルダ内に store.ts を作成しましょう。

image2

Redux の store を作成します。

Redux Toolkit のconfigureStoreが、store のセットアップを簡素化してくれます。

configureStoreの中には、状態を更新するためのreducerを設定します。

tsx
import { configureStore } from "@reduxjs/toolkit";
export const store = configureStore({
reducer: {},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

次に index.tsx に React Redux のProviderを設定します。

先程作成したstoreもインポートします。

tsx
import { store } from "./app/store";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);

src フォルダ内に、features フォルダを作成します。

features フォルダ内にさらに counter フォルダを作成し、counterSlice.ts を作成します。

image3

counterSlice.ts に初期状態とスライスを識別するための名前、状態を更新する方法を設定します。

今回は、初期状態をvalue: 23、スライスの名前をcounterとします。

状態の更新は、カウンターのように、incrementを実行すると 1 プラス、decrementを実行すると 1 マイナスとします。

tsx
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface CounterState {
value: number;
}
const initialState: CounterState = {
value: 23,
};
export const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
increment: (state: { value: number }) => {
state.value += 1;
},
decrement: (state: { value: number }) => {
state.value -= 1;
},
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

初めに作成した、store.ts に移動します。

reducer 内にスライスの名前とスライスの名前に Reducer を付けて指定します。

tsx
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});

App.tsx へ移動します。

React Redux のuseSelectoruseDispatchをインポートします。

また、store.ts からRootStateをインポートします。

さらに、counterSlice.ts からdecrementincrementをインポートします。

tsx
import { RootState } from "./app/store";
import { useSelector, useDispatch } from "react-redux";
import { decrement, increment } from "./features/counter/counterSlice";

ストアからデータを読み込むために、useSelectorを設定します。

Redux のactiondispatchするために、useDispatchも設定しましょう。

tsx
const age = useSelector((state: RootState) => state.counter.value);
const dispatch = useDispatch();

カウンターボタンを return 内に作成します。

tsx
function App() {
const age = useSelector((state: RootState) => state.counter.value);
const dispatch = useDispatch();
return (
<>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
+
</button>
{age}
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
-
</button>
</div>
</>
);
}

一通り完成したので、ブラウザで確認すると、

image4

初期値である 23 が表示されています。

+ボタンをクリックすると、

image5

数が 1 追加されました。

試しに、別のコンポーネントでも状態が管理できるか、確認してみましょう。

components フォルダ、Age.tsx

tsx
import React from "react";
import { RootState } from "../app/store";
import { useSelector } from "react-redux";
const Age = () => {
const age = useSelector((state: RootState) => state.counter.value);
return <>{age}</>;
};
export default Age;

App.tsx

tsx
<>
<Age />
<div>
<button aria-label="Increment value" onClick={() => dispatch(increment())}>
+
</button>
{age}
<button aria-label="Decrement value" onClick={() => dispatch(decrement())}>
-
</button>
</div>
</>

ブラウザで確認すると、

image6

Redux で管理している状態が、別コンポーネントでも使用することができました。

© 2024あずきぱんウェブスタジオ