React Docs BETAを読む 【ReducerとContextを使用したスケールアップ】
React Docs BETAを読む 【状態の管理】
React Docs BETAを読む 【Stateで入力に反応する】
React Docs BETAを読む 【状態構造の選択】
React Docs BETAを読む 【コンポーネント間で状態を共有する】
React Docs BETAを読む 【状態の保持とリセット】
React Docs BETAを読む 【状態のロジックをReducerに抽出する】
React Docs BETAを読む 【Contextでデータを深くに渡す】
に引き続き状態管理の章を読み進めていきます。
Scaling Up with Reducer and Context
ということでManaging Stateの最後の章です。
最後の章はReducerとContextを使ったスケールの話ですね。
Reducerを使って状態更新のロジックをまとめて、dispatchをContextで深く渡すことでネストが深く複雑な状態でも管理できるという話です。
Combining a reducer with context
状態のロジックをReducerに抽出する、という章で書いた通りReducerは状態更新のロジックを統合するのに役立ちます。
ただ、Reducerを使用しているコンポーネントでのみ使用可能で、そのコンポーネント下の子以下のコンポーネントでは使用できません。
なので他のコンポーネントで使用するためには状態とイベントハンドラが必要になってきます。
コンポーネントが多くなるとその分めんどくささは増していきます。
この状態を前の章では"prop drilling"と表記してありましたね。
状態とdispatchをコンテキストに置くことで上記の問題を解決しようという話ですね。
1. Create the context
useReducer関数は、現在の状態とそれを更新するdispatchを返してきます。
この2つを他のコンポーネントにも提供するために2つのContextを作成します。
- 状態を提供するContext
- dispatchを提供するContext
2. Put state and dispatch into context
Contextを作成したら、Providerを設置して必要なツリーにContextを提供できるようにします。
3. Use context anywhere in the tree
propsで渡している部分を削除してuseContextを使用して、状態とdispatchを使用したいコンポーネントで取得します。
こうすることで上位のコンポーネントで状態として持ちつつ他のコンポーネントにハンドラなしで状態と更新するための手段を提供できました。
Moving all wiring into a single file
必須ではないようですが、ReducerとContextを1つのファイルにすることでより整理できます。
Docsの例では2つのProviderを1つのコンポーネントにして、ReducerにすることでManageするコンポーネントが1つにできます。
こうすることのメリットとしてコンポーネントの関心を分離できるということですね。
Providerは状態とContextの管理に関心があるのに対して、使用するコンポーネントはViewに関心を集中することができます。
まとめ
今回の章がかなり実際のアプリケーションの動きを理解するのに役立ちました。
私が見ているコードは実際にはReduxを使用していますが、この章と同様の考え方で実装されていました。
もともとなぜこうするんだろうという疑問が初期に浮かんでいて、なんとなくで自己解決していたんですがこの章をよんではっきりと言語化できるようになりました。
Discussion