Redux Toolkitを使ってみた!
最近、Redux Toolkitを初めて使ってみました!
そこで今回は、Redux Toolkitについて、自分の備忘録も兼ねて、まとめてみたいと思います!
※自分が利用した関数などのみを取り扱うので、全てを網羅している訳ではありません。ご了承ください。
ライブラリについて
Reduxとは?
まず、Reduxとは何かについて、記載しておきます。
stateを管理・更新する、いわゆる「状態管理」のためのライブラリの1つです。
stateを更新するときには、dispatch関数を用いてactionがreducerに送られ、actionのtypeに応じた処理が実行されます。
Redux Toolkitとは?
次に、Redux Toolkitについてです。
Redux Toolkitは、Reduxを扱いやすくするためのライブラリです。
Reduxを単体で使うよりも、シンプルに記述できるようになっています。
Reduxを扱う標準的な手段になることを目指していて、Redux公式でも利用が推奨されています。
詳しくは以下のページを見てみてください。上記の説明も、こちらのページをベースにしています。
Redux公式ドキュメント What is Redux Toolkit?
React Reduxとは?
最後に、React Reduxについてです。
React Reduxとは、ReactとReduxをつなげるためのライブラリです。
Redux自体は、Reactじゃなくても利用することができますが、React Reduxは、Reactに特化しています。Reduxと合わせて使います。
詳しくは以下のページを見てみてください。上記の説明も、こちらのページをベースにしています。
React Redux公式ドキュメント Why Use React Redux?
Redux Toolkitを用いて状態管理をするのに用意するもの
それでは、ここからは、Redux Toolkitを用いて状態管理を行うにあたって必要なものについて、ご紹介していきたいと思います。
store
まずは、storeについて。
storeは、stateをまとめて管理するオブジェクトでした。
configureStore
関数を使って、reducerやmiddlewareを1つにまとめたオブジェクトを引数として渡します。
複数のreducerを渡すこともできます。
例としては、以下のようになります。
export const store = configureStore({
reducer: {
todo: todoSlice
}
});
また、TypeScriptを使っている場合には、stateの型を以下のように用意します。
RootState
という型を定義しているのですが、関数の戻り値の型を利用するReturnType
を用いています。
以下の場合、getState
関数でstoreで管理されているstateにアクセスし、typeof
で返されたstateの型を利用して型を生成していることになります。
export type RootState = ReturnType<typeof store.getState>;
slice
createSlice
関数を使って、reducerやstateに対応する、actionを作成・管理することができます。
例としては、以下のようになります。
const todoSlice = createSlice({
name: 'todos',
initialState, // stateの初期値
reducers: {
addToDo: (state, action) => {
let id;
if (state.todos.length === 0) {
id = 0;
} else {
id = state.todos[state.todos.length - 1].id + 1;
}
state.todos = [...state.todos, {id: id, title: action.payload, status: false}];
}
}
});
// Action Creatorをexport
export const { addToDo } = todoSlice.actions;
// reducerをexport
export default todoSlice.reducer;
reducers
で、reducerを定義しています。reducersオブジェクトのキー名とname
を使って、actionのtypeが生成されます。上記の例のtypeは、todos/addToDo
になります。Action Creatorは、reducersオブジェクトのキー名()
になります。
これまで、reducerは、switch文を用いて、actionのtypeに応じて処理を分岐させていましたが、createSlice
関数を利用することで、switch文による分岐を使わずに処理をreducersオブジェクトのプロパティとしてまとめることができ、わかりやすくなりました!
stateを更新する with React Redux!
ここからは、これまで作成したReducerなどを利用して、実際にstateを更新する方法についてご紹介致します。
以降は、React ReduxのAPIを利用していきます。
Provider
Provider
コンポーネントを利用することで、全てのコンポーネントからstoreを利用することができるようになります!
例としては、以下のようにして使います。
root.render(
<Provider store={store}>
<App />
</Provider>
)
Hooks
React Reduxでは、コンポーネントとstoreを関係づけるために、hooks
APIが用意されています。
stateの更新では、このhooks
APIを利用していきます。
useSelector
useSelector()
は、storeからstateを取り出すために使います。
例としては、以下のようになります。
// useSelector()を使って、stateを取り出してくる。
const todo = useSelector((state: RootState) => state.todo.todos);
return (
<ul>
{todo.map((item) => {
return (
<li key={item.id}>{item.title}</li>
)
})}
</ul>
)
useDispatch
useDispatch
は、dispatch
関数の参照を返します。dispatch
関数を利用できるようにするために使います。
これを用いて、引数にAction Creatorを渡すことで、state更新につなげることができます。
例としては、以下のようになります。
※フォームには、React Hook Formを利用しています。
const dispatch = useDispatch();
const { register, handleSubmit } = useForm<inputForm>();
const onSubmit: SubmitHandler<inputForm> = (data) => {
// dispatch()の引数に、Action CreatorであるaddToDo()を渡している。
dispatch(addToDo(data.todo));
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>Task:</label>
<input { ...register("todo")} />
<input type="submit" />
</form>
);
おわりに
Reduxは用語がややこしかったりして、理解するのが大変です。
しかし、Redux Toolkitを利用することで、かなりReduxを扱いやすくなることが実感できました!
認識の誤り・補足などがあれば、是非、コメントして頂けますと助かります〜!
お読み下さり、ありがとうございました!
参考資料
【TypeScript】Utility TypesのReturnTypeを深く理解する
React初心者でも読めば必ずわかるReactのRedux講座
Redux入門者向け初めてのRedux ToolkitとRedux Thunkの非同期処理
createSlice で楽に action と reducer を管理しよう
参考文献
じゃけぇ(岡田拓巳)著 『モダンJavaScriptの基本から始める React実践の教科書』(2021)
Discussion