はじめに
そもそも React ってなんだっけ?
いつもなんとなくこんな感じ〜で書いてるけど、これで本当にいいんだっけ?ってふと疑問に思った。
この「なんとなく使う」を脱却したく、原点に立ち返り、
React の公式ドキュメントにある React の流儀
を読んで、自分なりにまとめることにした。
ちなみに余談だけど React の流儀は、英語では Thinking in React だった。訳し方がカッコイイ!
React の流儀 まとめ
React で UI を実装するときの5つのステップ
ステップ1: UI をコンポーネントの階層に分割する
- モックアップのすべてのコンポーネントとサブコンポーネントを囲む、それぞれに名前をつける
- 1つのコンポーネントは理想的には1つのことだけを行うべきである(単一責任の原則)
- コンポーネントが大きくなってしまったら、より小さなサブコンポーネントに分解するべき
- モックアップ内にあるコンポーネントを特定したら、それらを階層構造に整理する
ステップ2: React で静的なバージョンを作成する
- インタラクティブな要素は加えずに、単にデータモデルから UI をレンダーするバージョンを作成する
- コンポーネントを作成する際に、他のコンポーネントを再利用しつつ、props 経由でデータを渡すようにする(ここではまだ state を使わない)
- 階層の一番上のコンポーネントが、データモデルを props として受け取り、下の階層にあるコンポーネントに流れていく構造をつくる(単方向データフロー)
ステップ3: UI の状態を最小限かつ完全に表現する方法を見つける
- ここでようやく state が登場する
- state の構造を考える上で最も重要な原則は DRY(Don’t Repeat Yourself: 繰り返しを避ける)
- state の見分け方
- 時間が経っても変わらないもの → state ではない
- 親から props 経由で渡されるもの → state ではない
- コンポーネント内にある既存の state や props に基づいて計算可能なデー → state ではない
- それら以外で残ったものが state
ステップ4: state を保持すべき場所を特定する
- state を置く場所の決め方
- ①その state に基づいて、何かをレンダーする 全てのコンポーネント を特定する
- ②階層内でそれら全ての上に位置する、最も近い共通のコンポーネントを見つける
- ③state がどこにあるべきか決定する
- 多くの場合、state をその 共通の親 に直接置くことができる
- state を、その共通の親の さらに上にあるコンポーネント に置くこともできる
- state を所有するのに適切なコンポーネントが見つからない場合は、state を保持するためだけの新しいコンポーネントを作成し、共通の親コンポーネントの階層の上のどこかに追加する
ステップ5: 逆方向のデータフローを追加する
- ユーザの入力に従って state を変更するには、逆方向へのデータの流れをサポートする必要がある
- set 関数を props で渡す
所感
サンプルコードも眺めてたんだけど、コンポーネントの認識が実はズレてるかもしれないことに気づいた。
コンポーネント = 再利用できる = 同じものが複数出てきたらそれらをまとめる
だと思ってた。
しかし、サンプルコードを見るとどうも違う。
小さいパーツ毎にコンポーネントにしており、それらをいい感じにグルーピングして新たにコンポーネントを作っている。
そうか。単一責任の原則が抜けているのか。
React の言う「コンポーネント」ってそういう意味で使っていたのか・・・。
おそらく現場では UI が確定しないうちから実装を始めているので、ステップ1やステップ2が抜け落ちているのかもしれない。
最初のうちは仕方ないかもしれないが、UI が出てきたら、一度立ち止まってコンポーネントの分け方や階層構造の見直しなどを行う必要があるのではないだろうか。
Next Action
サンプルコードを眺めてるだけじゃ分からないこともあったので、実際に手を動かしてコーディングしてみようと思う。
こんなに小さくコンポーネントを分けたことがないので、実装の流れを把握できるようにしたい。