2019.02.18 更新 Dan Abramov さんによって元記事が更新されました。いまはHookが使えるので、この記事にこだわりすぎるな、とのことです。
Redux を使うにあたって、どのようにコンポーネントの使い分けるかということについて、下記のサイトが非常にわかりやすかったので、忘れないようにメモしておきます。
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
コンポーネントにおける 2 つの分類
Presentational Component
- 見た目に関する責任を負う。
- 子要素として、Presentational Component、Container Component のどちらも持ちうる。
- DOM マークアップやスタイルを持つ。
- this.props.children を受け取る。
- 自分のコンポーネント以外のことについて依存しない。(例:Flux アクションや Store など)
- データを自身で勝手に読み込んだり、改変しない。
- データやコールバックは、親から Props として受け取る。
- State を持つことは少ない(持ったとしても、自身の UI に関する状態だけ)。
- Functional Component として書かれる。Component State や Lifecycle Hook、パフォーマンス調整の必要がなければ。
- 主な使用例:Page, Sidebar, Story, Userinfo, List
Container Component
- アプリケーションの動作に関する責任を負う。
- 子要素として、Presentational Component、Container Component のどちらも持ちうる。
- DOM マークアップやスタイルを持たない。
- データ及びデータを扱うためのファンクションを Presentational Component に提供する。
- Flux Action を発火する。また、発火するためのファンクションを子要素に提供する。
- State を持つ。データソースとして機能する。
- react-redux.connect()などの HOC を使って生成される。
- 主な使用例:UserPage, FollowersSidebar, StoryContainer, FollowedUserList
比較
以下、redux 公式サイトより。
Presentational Components | Container Components | |
目的 | 見た目(markup, styles) | 働き(データ取得、state のアップデート) |
Redux | 関係なし | 関係あり |
データの取得 | props | Redux state を subscribe |
データの変更 | props から取得した Callback を使う | Redux の actions を Dispatch する |
作成方法 | 手動 | React-Redux の connect() |
この分け方にするメリット
- アプリケーション部分と UI 部分を分離できる
- 再利用性が高い
- Container に重複したレイアウトを記載しなくなる。(Sidebar や Page といったレイアウトを Presentational Component として抽出することを強制される。Container から、レイアウトコンポーネントに対して children を渡してやるスタイル。)
どのように Container を使い始めるか
Presentational Component だけでアプリを作り始めるのがおすすめ。そのうち、データを親から受け取って子供に渡しているだけの、無駄に大きい中間コンポーネントが発生する。それを Container にするとよい。とのこと。