今はHooksが使える時代なのであまりこの考え方はしないようになってきていますが、過去の案件のソースとかを読む場合に知っておくと良い概念かと思いましたので、まとめておきます。
Reduxを使うにあたってどのようにコンポーネントを分けるかの思想のことです。
Presentational Component
特徴
- 見た目の責務を担う。
- 関数コンポーネントで作られていた。(今まではHooksがなかったので状態を持てなかったため。)
- ReduxのStoreに依存しない。
- DOM マークアップやスタイルを持つ。
- 子要素として、Presentational Component、Container Component のどちらも持ちうる。
- データを自身で勝手に読み込んだり、改変しない。
- データやコールバックは、親から Props としてchildrenを受け取る。(childrenをマークアップに埋め込むだけにする。)
- State を持つことは少ない(持ったとしても、自身の UI に関する状態だけ)
Container Component
特徴
- アプリの動作の責務
- 本当にロジックだけを書く。
- ReduxのStoreに依存する。
- 子要素として、Presentational Component、Container Component のどちらも持ちうる。
- DOM マークアップやスタイルを持たない。
- dispatchできる。
二つに分けるメリット
アプリケーション部分とUI部分に分離できる。
見た目を変更するからと言ってロジックも合わせて変更するパターンは稀なので保守性が高くなります。
また、Container ComponentはPresentational Componentに加工したpropsを渡すだけなのでロジックに対するテストも簡単になります。
再利用性が高くなる。
Containerに重複したレイアウトを記載しなくなる。
二つに分けるデメリット
どの粒度でContainer層を導入するのか判断するのが難しい。
大抵は親コンポーネントをContainerにして子や孫にpropsをバケツリレーしていく形が採用される。それだとコードの見通しがかなり悪くなる。親と孫の間にもContainerとかを用意すればまだ見通しはマシになるが、それだと今度はContainerの数が増えすぎる問題が発生する。Hooksで登場した
昨今では
2019年にHooksが登場して「useSelector」や「useDispatch」を使えばContainerの粒度を考えるのが大変なデメリットに対応できます。
HOC(Heigher-Order-Component)とは?
- 高階コンポーネント
- コンポーネントを引数にとりコンポーネントを返す関数
- react-reduxのconnect関数やReact.memoはHOCです。
- React界隈で一時期流行ったが、hooksの登場で下火になりました。
使い所
あるコンポーネントによく使う機能を追加したい場合に使います。(別の言語とかであれば、「デコレータ」とかが該当する文法になりそうです。)
例
ユーザーがログインしている場合のみあるコンポーネントを付け足す。
reduxのconnect関数
react-reduxのconnect関数はHOCです。mapStateToPropsとactionsをコンポーネントのthis.propsに渡しています。
React.memo
コンポーネントを引数としてとり新しいラッパーコンポーネントを返します。
メリット
- ロジックをきれいに分離できる。
- 1関数1役割にしやすい。
デメリット
- HOCから渡されるprops名が重複すると使えない。
- ラップされる側から見て、親から渡すpropsかHOCからくるpropsか判断できない。
実装方法
- コンポーネントでよく使うロジックを書き出してHOCとして外だしする。
- propsとconfigとbehaviorの全てをchild componentに渡せるようにする。
この記事へのコメントはありません。