説明
リデューサは大きくて複雑な state を扱いたいときに使うやつ。値同士が連動しているというか、あっちに値をセットするたびにこっちのフラグが変化するとかそういう場合に便利。もともとReactと併せてよく使われてたReduxと同じ。
フック API リファレンス – React
使い方だけならそんな難しいことは無いと思うのだが、個人的にはTypeScriptでキレイに書こうと思うと毎回書き方が安定しない。なのでこの記事では、メモも兼ねて筆者が最近やってる書き方をサンプルコードにしておく。
サンプル
サンプルの内容をまとめると以下。この画面の描画に必要な情報をリデューサで管理してみる。
- 画面表示時に非同期でユーザ情報を取得する。取得中は画面に「読み込み中」と表示する。
- ユーザ情報を入力フォームで変更できる。
- リセットボタンを押すと、入力フォームの内容が変更前の状態に戻る。
- 保存ボタンを押すと、入力フォームの内容を保存する。
- 保存ボタンはユーザ情報が変更されている場合のみ押すことができる。
See the Pen
using-reducer-with-react-hooks-and-typescript by napoporitataso (@napoporitataso)
on CodePen.
以下、作り方。
準備
以下コマンドで必要なパッケージをインストール。
この記事を書いた時の各パッケージのバージョンはこんな感じ。
ほか、各種設定ファイルはこんな感じ。適当。
ソースコード
ディレクトリ構成
サンプルコードのディレクトリ構成は以下の通り。
ストア
リデューサはstateとそれを操作するための手続きのかたまりなので、本当はそれを扱うコンポーネントと同じファイルに書くのがいいのではと思うのだが、リデューサのコードが肥大化することを考えると別ファイルにするのが良いと思う。
Reduxではそのかたまりをストアと呼んでいたので、ここでは stores/UserStore.tsx
というファイルに分離する。
また、アクションごとに型を定義して、アクション自体はそのUnion型 (判別可能なUnion型) で扱うようにする。
それ以外のコード
何の変哲もない index.html
と index.tsx
。
次にリデューサを使う <App>
コンポーネント。
上で作った UserStore
から useUserStore()
をimportして実行すると、state
と dispatch()
を取得できる。state
から値を取り出して画面を描画したり、イベントをトリガーに dispatch()
を実行して state
を更新したりする。
実行方法
上記のサンプルコードを全部用意して以下コマンドを実行すると、ブラウザ上で動作確認できるはず。
以上。