【React/Vue】なぜコンポーネントベースでWebアプリを作るのか

React/Vue などを使ってフロントエンドを開発する際、基本はコンポーネントベースで設計・開発すると思います。
**なぜコンポーネントベースなのか**、**どういうメリット・目的があるのか**、今一度確認する機会があったので記事にします。

**コンポーネントベース以外経験が無い方へ**
Web アプリの学習を始めて間も無い方の中には、そもそもコンポーネントベース以外経験がない方も居るかもしれません。
そんな方は極端な例ですが、Web アプリの画面が**もし１画面１コンポーネントで作られていた場合**と**小さなコンポーネントを積み上げて作られていた場合**を想像し、以下の記事では後者のメリットが書かれていると思って読んでみてください。

# コンポーネントが持つべき 5 つの特徴

はじめにコンポーネントのあるべき姿ついて確認しておきます。

1.  **単一責任の原則**
    コンポーネントが責任を持つ問題は 1 つにするべきです。
    ソースがシンプルになることで可読性が向上します。
    また、ソース変更時の影響範囲が明確になることで保守性が向上します。

1.  **カプセル化されている**
    コンポーネントを使いたいとき、インターフェースだけ知っていれば内部の実装を気にしなくて良いです。

1.  **置換可能である**
    インターフェースさえ同じであれば違うコンポーネントに差し替えることができます。

1.  **再利用可能である**
    再利用可能なコンポーネントは、そのコンポーネントが担っている責務に対して過不足なく機能を提供していると言えます。
    「過不足なく」というのは意外と難しく、特にありがちなのが機能を過剰につけてしまうことです。
    ある画面の文脈では必要な機能でも、別の画面では邪魔になることもあります。
    **コンポーネントの責務を常に意識し、再利用性を損なうことがないようにすることが大切です**。

1.  **組み合わせて別の大きなコンポーネントを作成可能である**
    再利用性が十分に高いことの裏付けです。
    一つ一つのコンポーネントは小さな問題しか解決できませんが、大きな問題を小さな問題に分割し、**適切なコンポーネントに振り分ける役割を持つコンポーネント**を作れば、それ自体が大きな問題を解決するコンポーネントになります。

# コンポーネントベースのメリット

先に紹介した 5 つの特徴を持つコンポーネントで Web アプリを構成すると以下のようなメリットがあります。

## １．複雑な UI も確実に組み立てられる

コンポーネントベース最大のメリットは**複雑な UI を確実・堅牢に組み立てられること**です。

### 堅牢な UI 開発を実現する

  多くの機能を提供するアプリでは複雑な UI 設計が求められます。
  例として Facebook の Web アプリを見てみると、ヘッダー・サイドメニュー・投稿記事リスト・広告など沢山の UI が並んでいます。
  これらの UI がもし互いに依存しているような作りになっていた場合、意図せずバグを産んでしまうことがあります。
  （ある UI の機能を変更したら別の UI が動かなくなった、ある UI のレイアウトを変更したら別の UI のレイアウトが崩れてしまった、など）
  **コンポーネント化された UI が個別で不具合なく動作することがテストされていれば、それを正しく使ったアプリの品質も保証できます**。

### コンポーネント単位でテストできる

  **アプリの品質を担保するための最も重要なポイントです**。
  UI はアプリに組み込まれるとアプリ全体の状態に左右されてしまうことが多いので、単体でテストすることが難しいです。
  **コンポーネント化して独立した UI であればアプリの状態に依存せず単体でテスト可能です**。
  適切に分割された小さな実装であれば必要なテストケースも少なく、テスト項目も作りやすいです。

### 不具合のリスクポイントを減らすことができる

  一般的に**書くコードの量が減ればバグの量も減ります**。
  再利用可能なコンポーネントを作成することで全体のコード記述量を減らすことができます。

### メンテナンスがしやすくなる

  **UI に変更を加えた際に影響を受ける範囲がコンポーネント内に留まるので、メンテナンスがしやすいです**。
  見た目だけを責務とするコンポーネントであれば、修正作業はエンジニアではなくデザイナーが直接行うこともできます。

### 解決する問題を小さくすることで不具合発生リスクを減らす
  **複雑なコードより簡単なコードの方が不具合発生リスクは低いです**。
  一つ一つのコンポーネントが単純な問題を解決するために作られているのであれば、内容は簡単になり実装の難易度も低くなります。

## ２．開発作業を効率化する

コンポーネントベースは品質を担保するとともに開発速度向上にも繋がります。

### 再利用で実装量を減らす

  **再利用しやすいコンポーネントを作ることは開発速度向上に直結します**。

### 並行開発で待ち時間を減らす

  画面単位の開発ではなくコンポーネント単位の開発だと、**１画面に必要な UI を複数人で並行開発することも可能です**。
  各コンポーネントは独立しているため、他のタスクに依存せず開発可能です。

### 仕様変更による手戻り作業を効率化する

  画面単位で UI 開発していた場合、画面仕様に変更があれば必ず手戻りが発生します。
  **小さなコンポーネントを積み上げて大きな部品を開発する方式だと、仕様変更によって影響を受けるコードは比較的少なくなります**。
  また大きな部品ほど後から作られるので、仕様変更のタイミングでまだ画面自体の実装に着手していない可能性もあり、その場合手戻りは無くなることもあります。

### 新規参入開発メンバーを最短で戦力化する

  **コンポーネント内で使用する技術スタックだけ知っていれば開発可能**なので、サービス背景についての知識は概要だけで良い場合もあります。

### 複数のテスト・アプローチでテスト工数を下げる

  **コンポーネントがアプリに依存しない環境で単体実行できる**ので、さまざまなアプローチでのテストが可能です。
  画面に依存している UI ではテストしづらいケースを時間をかけて再現し、何とかテストするということもしばしばありますが、独立したコンポーネントだと単独のテストなら非常に簡単に行うことができます。

### 複数アプリケーションの開発を容易にする
  UI コンポーネントが部品としてアプリから分離できる形になっていれば、**別のアプリでコードを再利用することが可能です**。
  仕組み次第では**複数アプリから同じコードを参照して、全体のメンテナンスコストを下げることもできます**。
  ただしコードを変更したときの影響範囲がかなり大きくなるので、より堅牢な運用が必要となります。

## ３．ユーザーメリット

ここまではアプリを開発するエンジニアが受けるメリットの紹介でしたが、アプリを使うユーザーにとってもメリットがあります。

### 多機能アプリのユーザービリティ向上
  アプリが多機能になるとたくさんの UI を画面に表示するため複雑になります。
  **ある UI コンポーネントが別の画面で使われていたとしても、ユーザーはすでにその UI コンポーネントの使い方を知っているため、すぐにその機能を使い始めることができます**。

# まとめ

**コンポーネントが持つべき 5 つの特徴**

1. 単一責任の原則
1. カプセル化されている
1. 置換可能である
1. 再利用可能である
1. 組み合わせて別の大きなコンポーネントを作成可能である

<br />

**コンポーネントベースのメリット**

**1.複雑な UI も確実に組み立てられる**

- 堅牢な UI 開発を実現する
- コンポーネント単位でテストできる
- 不具合のリスクポイントを減らすことができる
- メンテナンスがしやすくなる
- 解決する問題を小さくすることで不具合発生リスクを減らす

<br />

**2.開発作業を効率化する**

- 再利用で実装量を減らす
- 並行開発で待ち時間を減らす
- 仕様変更による手戻り作業を効率化する
- 新規参入開発メンバーを最短で戦力化する
- 複数のテスト・アプローチでテスト工数を下げる
- 複数アプリケーションの開発を容易にする

<br />

**3.ユーザーメリット**

- 多機能アプリのユーザービリティ向上

<br />

コンポーネント設計をする際にはこれらを意識することでより良い設計ができるかもしれません。
最後に注意点ですが、現実問題として**Web アプリは必ずしもこの記事で紹介したようなコンポーネントだけで作られるわけではありません**。
例えば[AtomicDesign](https://design.dena.com/design/atomic-design-%E3%82%92%E5%88%86%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%A4%E3%82%82%E3%82%8A%E3%81%AB%E3%81%AA%E3%82%8B)で言うところの Pages は、実際のコンテンツに影響されるため**カプセル化はできず**、さらに**再利用もできません**。
**React/Vue で書くソース全てが上記の目的を持って書かれるわけではない**ことは頭に入れておきましょう。

読んでいただきありがとうございました。