前回に続いて、React Hooksについてまとめていきます。
useReducer
useReducerは状態を管理するためのReact Hookで状態を操作する複数のアクションに基づいて状態を更新することができます。
useStateと違うことは状態を操作するための具体的な操作を複数定義できるところにあります。
例えばログインフォームでユーザー名やパスワードを管理する時にそれぞれを更新する操作を定義する場合にはuseReducerが適しています。
「reduce」とは「減らす」「縮小する」って意味で、useReducerとは初期値をアクションに基づいて更新することで状態を縮小するって意味なんだと思います。
次のサンプルではuseReducerを使用してフォームの入力を扱う例を示しています。
useRecuerは第1引数に状態を操作するアクションを定義して第2引数に状態の初期値を指定します。
dispatchに渡すオブジェクトはアクションオブジェクトと呼ばれます。
アクションオブジェクトにはtype
プロパティを含む必要があります。
サンプルの例では、typeにフォームの要素でどれを更新するかのアクション名を指定して、payloadに更新される値を渡しています。
useCallback
useCallbackの解説に入る前に、JSでは関数、オブジェクト、配列は自身と比較される場合にのみに同値となるのを念頭に入れておかねばなりません。
1 2 3 4 5 |
const a = () => { return 1; } const b = () => { return 1; } a === b // false a === a // true |
また、コンポーネントで使用される状態が更新されるたびにそのコンポーネントは再描画されるというのも念問に入れておく必要があります。
useCallbackでラップした関数は依存関係が更新されるまでは常に同じ関数オブジェクトであることが保証されます。
例えば次の例ではuseCallbackフックを使用することで子コンポーネントに渡したコールバック関数がボタンをクリックするまでは更新されていないことを示しています。
うん、正直例えが下手なのは認める。
ただ、通常はフォームの入力をするたびにhandleClickも新しい関数オブジェクトになるためChildComponent内のuseEffectが毎回発火することになるのが、
countが更新されるまでは同じ関数オブジェクトであるのが保証されるので、それまではuseEffect内の処理が実行されないというのがuseCallbackを使うことによって実現ができるようになる。
というのが言いたいのです。
useMemoについても大体似たような機能なのですが、それは次回に回します。
まとめ
- useReducerを使うとuseStateよりも詳細な状態変化の指示を定義することができるので、フォームの更新など複雑なオブジェクトを操作する時には使った方が良さそうです。
- useCallbackは正直使い所が難しいですが、再描画による関数の再定義を制御したいケースには使えるかもしれません。