Reactコンポーネント設計についてのLTイベントに参加した
テーマは5つで「分割粒度」「構造」「スタイリング」「テスト」「パフォーマンス」
前提としてお二人ともにSPA Next.jsでSSRはあまり力を入れてやってない状況とのこと
分割粒度
よしこさん
Componentは 大きく3種類の分類でディレクトリを切ってる。
【page】
エントリーポイントで 1体位になるもの(Next だとsrc/pagesとか)
全部本体をそこに入れていくのではなく、本体は別でこのcompotentsの中のpageに切り出している。ルーティングの変更でディレクトリ階層間のファイルの移動が発生するので、そちらにComponent定義を巻き込みたくなかった為と。。
【 model】
modelが1番 大きくてま何らかのドメインモデルに関連
するものをドメインモデルごとにディレクトリで 切ってる。
【ui】
modelに関心を持たない、見た目を伴うComponent
こちらの記事でもっと詳しく解説されてる。
うひょさん
うひょさんはさっきのよしこさんでいう所のModelの中でどう分けるかの話
「1ロジック1コンポーネント」という考え
「ボタン等を押したらなんらかのアクションが起こる」というロジックが複数あった場合に1 つのコンポーネントでまとめてしまうとディレクトリがごちゃつく印象があるので、2つのロジックが出てきたら基本的に分けるようには心がけてる。
ロジックコンポーネント+まとめコンポーネントの構成
レイヤー切りとしてはmodelとUIをそこまではっきり分けるという意識はない
UIコンポーネントは共通化されたデザインの場合に発生する印象
その場限りの場合はあまり分けない
構造
よしこさん
コンポントの本体としてはtsxが1個 あるだけであとスタイルがCSSに出てるっていうような構成
1コンポーネントを複数ファイルにいっぱい分け るっていうよりかかは大きくなるのであれ ばそのコンポーネントそのものを複数に分けるみたいな方をやる
行数にはこだわりない
どんなUIが返されるのか?さえわかればよい。コンポーネントを入れ子にしすぎるとわかりづらくなる。
ベタ書きがわかりやすかったりする。妥協点としてそのコンポーネントでしか使用しないカスタムフックを定義しておく
Render propsは不評
複数 コンポーネントを組み合わせる時にステートの中に閉じ込めたくてレンダー プロップス使ってた。チームメンバーがレンダー プロップスいっぱい固ってると読めませんみたいになって意外と不評だった
うひょさん
1コンポーネント1フックが好き
コンポーネントのロジック部分を抜き出して隣に置くことでロジックのアウトプットが明確になる
ロジックが複雑になってしまうみたいな時にはコンポーネント専用のフックを コンポーネントの隣に置く
コンポーネントの中になんか途中計算の変数が10個あるみたいな状態になると その途中計算の変数を好き勝手にjsx から使われると結構大変
ロジックの最終結果は何かっていうことを インターフェイス上明確にするために1 コンポーネントでもフックを抜き出す。
レンダーフックスって呼んでるパターンが好き。コンポーネントとフックの依存関係をこれから逆にした パターン。レンダーのパターンとして好きで使うべき時には使っている。
スコープを限定する
テストしやすくする目的??
コンポーネントの肥大化避けれる
U Iの コードからやっぱりロジックをなるべく抜き出してカプセル化したいなって思うと フックスにやっぱり逃していく流れになる
ベタ書きの方が手早く 終わるので見通しも良いし変更手っ取り早い (壊れやすいけど)
妥協点としてやっぱり コンポーネントのファイル内にそのコンポーネントしか使わないフックスを 置いとくとかで、近くに置くを心がける感じではやってる。
昔は結構 遠い場所にあるような形で細切りにするパターン昔多かったが
最近はコロケーションのような関心の近いものは近い場所に置くパターン多いかも
テストファイルとかも別に ディレクトリー上で切るんじゃなくて
そのコンポーネントのディレクトリーの中 に入れたりとかする。
コロケーション大事とお二人。
コロケーション関連記事:後で詳しく読みたいと思ってる。。
スタイリング
スタイリングに関してはこのイベントに出てる方は全員CSS Modulesがいいとの見解
小回りがきくし潰しも効くから
CSSの構文が直接使えるのはやっぱり偉い
CSSのいろんな機能に一番早く キャッチアップすることができる**
暗黙の依存関係は避けたい
親コンポーネントがdisplay:flexを持ち
子コンポーネントがflex:1とかを持ってるのは避けたい。セットは同じとこに詰めたい
テスト
よしこさん
コンポーネントのテストてこうどこをどうテストすべきなんだろう思ってると
ユニットテストもリポジトリーとかスケースとかセレクター とかはなんかセットでテストも作ってるが、ユースケース呼んだらこのリポジトリーが呼び出される みたいなの書いては見るけどなんかあんま 本質的じゃない気がするなみたいな思いもあるとの事。
うひょさん
コンポーネントのテストで1番テストしたい所はそのコンポーネントに含まれるロジックの部分
ユニットテストで カバーできるのであれもどんどん書いたら いいなと思う一方でそれ以外の部分はあんまり価値のあるテストにするの が難しいの印象を持っているとの事
どうせU Iのテストをするならブラウザー 動かしてていうような考え方を持っているとの事
RSCでフックですらなくなる。できるだけRSCに寄せて、テストを簡単にしていく
フックはま基本クライアントサイドで実行するものっていう前提があっ てリアクトサーバーコンポーネントの方で 何かしらテストすべきロジックがあるとすると限りなく純粋な関数に近づくのでは・・・
依存関係増やしてアップデートしたくないそうなってくるとやっぱりユニットテストっていう ところに収束しがち
VRTの誤検出を減らしてく活動は意味がある。
見た目のテストはVRTじゃないとできない
スナップショットは今やってない。優先度低い
DOM比較しても見た目の保証ができないのが辛い。VRTまで行った方がいいのでは
パフォーマンス
コンポーネントを 適切に分けてあとSuspenseの価値は大きい
ネットワークの往復を1往復減す事がパフォーマンスとしてのメリットとしては 大きい。
それを生かせるコンポーネント設計にするのが大事。
1番最初に出すのに必要なものだけを取得して他はサスペンスの下 に押し込んでしまう
取得できてない分は適切な ローディング、スケルトン 的なものを活用するこによってま体感のパフォーマンスっていうの を確保することが重要
Suspense
レイアウトシフトの対策もやっぱり重要。
バンドルサイズとかはまあんまりま気にし ないことはないかもしれないけどそれより優先すべきことがある