🔥

Reactの設計手法について調べてみた

2022/12/24に公開

Reactの設計手法について調べました。

主要な設計手法

現状、Reactで使われている主要な設計手法について調べた感じ、以下の2つの情報が多くありました。

  • Atomic Design
  • Container/Presentational

Atomic Design

https://atomicdesign.bradfrost.com/

デザインをパーツやコンポーネント単位で定義していく手法で、UIの要素を下記の5段階に定義します。

  • Atoms(原子)
    • コンポーネントの最小単位。入力InputやButtonのこと。
  • Molecules(分子)
    • 原子を組み合わせて作られるコンポーネント単位。入力フォームや検索フォームなど。
    • 原子と分子のレベル分けは単一責任の原則遵守にも役立つ。
  • Organisms(有機体)
    • 原子、分子の組み合わせ、集合。
    • 原子と分子は再利用を前提としているが、有機体は特定の機能を前提としている為、基本的にそのままでは再利用はできない。
  • Templates(テンプレート)
    • 有機体の組み合わせ、集合。
    • レイアウトやコンテンツ構造を表したもの。
  • Pages(ページ)
    • 最終的にユーザーの目にふれるもの。

詳しくは本家サイトなどを参照してみてください。

Atomic Designのメリットとデメリットとしては以下のようなものがあげられます。

  • メリット
    • デザインが小さな単位で管理されている為、修正がしやすく、変更コストが抑えられる。例えばボタンのデザインを少し変えたいという時も原子レベルでデサインされている為、変更を適用しやすい。
    • 原子レベルまでデザインが定義される為、デザインが明確になる。デザイナーと開発者の意思連携がしやすい。
    • 原子、分子レベルでデザインがされるため、再利用、共通化がしやすくなる。
  • デメリット
    • 各単位について、明確な基準を設けないと人によって判断が変わり認識齟齬が発生する。
    • コンポーネントが増えた時のビルドが重くなる。
    • 人が管理する範囲が増える事によるコスト増。

Atomic Designをそのまま適用している所は少なそうで、Atomic Designの記事を出している方は、いずれもなんらかの工夫、カスタマイズをされていました。

Container/Presentational

https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
https://www.yuuniworks.com/blog/2018-05-18-presentational-componentとcontainer-component/

ロジックとUIを分離することで関心の分離を図るデザインパターン
詳細は上記サイトなどを参照してみてください。

Update from 2019: I wrote this article a long time ago and my views have since evolved. In particular, I don’t suggest splitting your components like this anymore. If you find it natural in your codebase, this pattern can be handy. But I’ve seen it enforced without any necessity and with almost dogmatic fervor far too many times. The main reason I found it useful was because it let me separate complex stateful logic from other aspects of the component. Hooks let me do the same thing without an arbitrary division. This text is left intact for historical reasons but don’t take it too seriously.
2019年からの更新:私はずっと前にこの記事を書きましたが、それ以来私の見解は進化しています. 特に、このようにコンポーネントを分割することはお勧めしません。 あなたのコードベースでそれが自然だと思うなら、このパターンは便利です。 しかし、私はそれが何の必要性もなく、ほとんど独断的な熱意で施行されているのを何度も見てきました. これが便利だと思った主な理由は、複雑なステートフル ロジックをコンポーネントの他の側面から分離できるからです。 フックを使用すると、恣意的な分割なしで同じことができます。 このテキストは歴史的な理由からそのまま残されていますが、あまり真剣に受け止めないでください。

上記は発案者の方の原文ですが、hocksが登場したので、現状ではContainer/Presentationalパターンは推奨していないといっています。

ですが下記サイトの言われている通り、hocksが使えるようになった現在でもContainer/Presentationalパターンは適用メリットがあるという意見もあり、私もこの意見に賛成です。
https://zenn.dev/kazu777/articles/9460c75b7cd8d1#hooksによるcontainer%2Fpresentationalパターンの置き換えについて

Container/Presentationalパターンのメリットとデメリットとしては以下のようなものがあげられます。

  • メリット
    • UI層とロジック層が分かれるので責務が明確化する。
    • テストがやりやすくなる。
    • Presentational Componentはpropにのみ依存するので再利用がしやすくなる。
  • デメリット
    • コードの記載量が肥大化する。
    • コンポーネントのネストが深くなる。
    • UI層とロジック層の粒度判断が難しい場合がある。
    • propのバケツリレーで見通しが悪くなる。

ロジックと表示を分類する手法

ロジックと表示を分類する手法なら別に以下のような手法もあります。

  • 高階コンポーネント(HOC)
  • children propsの拡張
  • componentのprops渡し

https://qiita.com/teradonburi/items/6828635d2e70dba6637d#presentationビジネスロジックとviewを分離する

他の設計手法

Compound Components

https://qiita.com/seya/items/d08b8a6c12f3e71d5971
https://tyotto-good.com/blog/compound-component

High Order Component (HOC)

https://ja.reactjs.org/docs/higher-order-components.html

Render Props

https://ja.reactjs.org/docs/render-props.html

デザインパターンまとめ情報

https://zenn.dev/morinokami/books/learning-patterns-1/viewer/hoc-pattern

SOLID原則

  • 単一責任の原則
  • 開放閉鎖の原則
  • リスコフの置換原則
  • インタフェース分離の原則
  • 依存性逆転の原則

https://www.youtube.com/watch?v=MSq_DCRxOxw&t=199s
https://zenn.dev/koki_tech/articles/361bb8f2278764

分割統治法

きな問題を小さな問題に分割し、その一つひとつを解決することで、最終的に最初の大きな問題を解決することに繋げる、という問題解決の手法。

元は数学の問題解決手法で、Reactのコンポーネント志向の元にもなっている。

独自性の高いアーキテクチャ構成

下記のように独自性の高いアーキテクチャ構成を考えられて採用されている方もいました。

https://zenn.dev/yoshiko/articles/32371c83e68cbe
https://zenn.dev/mutex_inc/articles/beca85dd7fdcae

他にはMVVM構成などもあるでしょう。

https://paulallies.medium.com/clean-mvvm-with-react-and-react-hooks-ebc37b22542f

その他有用な情報

https://zenn.dev/kamy112/articles/962a38d6294644
https://qiita.com/teradonburi/items/6828635d2e70dba6637d

まとめ

自分が現状で実際にReactの設計する際にはContainer/Presentationalパターンの亜種で、Atomic Designのいいところも取り入れたような設計になるかなという感想です。

アーキテクチャ構成を考えるときにはトレードオフ判断が必要なので、それぞれの設計手法の考え方だけでなく、メリット・デメリットも把握しておくのが肝要という所でしょうか。

また設計手法にプラスして各種ライブラリ、SWRやReact Hook Formなどの活用方法、テストコードの具体的な実装イメージ、プロジェクトの規模や種類、チームメンバーのスキルセットなども考慮事項に加わってくるのかなと思います。

Discussion