Reactのディレクトリ構成を検証する【Atomicデザイン編】

## はじめに

React公式はディレクトリ構成について、自由に決めていいよ〜という見解です。

> お勧めの React プロジェクトの構成は？　
React はファイルをどのようにフォルダ分けするかについての意見を持っていません。

しかし（存在するなら）ベストプラクティス構成で実装したい。

そこで、巷でよく使われているディレクトリ構成を検証し、それそれの利点を探っていこうと思います。

- **Reactのディレクトリ構成を検証する【Atomicデザイン編】** ←いまここ
- Reactのディレクトリ構成を検証する【bulletproof編】

## Atomicデザインとは？

こちらの記事が参考になります。
https://zenn.dev/hikary/articles/41b5f9747fe83f

## 前提条件

- 技術記事リンクデモサイトを作成し、ディレクトリ構成を検証
- 見た目と機能は変更しない、パッケージは同じバージョン
- 主な技術スタック
    - React
    - Vite
    - typescript
    - tailwind

## 成果物

**技術記事リンクデモサイト**
レンダリングの様子を観察するため、レンダリングのたびに要素が黄色くなります。
https://hacker-news-react-atomic.vercel.app/

**GitHub**
https://github.com/Nyamadamadamada/hacker-news-react-atomic

参考にしたサイト
https://github.com/SankThomas/hacker-news


## 私見による評価
![スクリーンショット 2022-12-05 21.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650886/b5c4c516-937c-155d-31b6-3de56452bf89.png)
評価基準と所感の詳細を以下に記載します。

## Reactの設計原則に則っているか
Reactの思想に近いディレクトリ構成であればベストプラクティスのはず、ということでReactの設計原則に関連する３項目を評価対象にしました。

- **宣言的なView**
    - 関連するコンポーネントのみ更新、描画する
    - 無駄に再レンダリングしない
- **コンポーネント**
    - UIは独立し、再利用できる部品であるか
- **単一責任の原則**
    - ひとつのコンポーネントはひとつの役割だけをするべき

### 宣言的なView
評価は３。

Atomicデザインは要素を細かく分解するため、要素数が多いです。
そのため、要素ごとに再レンダリングを抑えるコードを書けば、再レンダリングを抑えることができます。

反面、関連する要素が多い変数が更新された場合の処理も多くなる可能性があります。更新処理が起きたとき、どの要素に影響するのかを考慮するためには、ある程度技量が必要と考えられるので評価を３にしました。

### コンポーネント
評価は４。

Atomicデザイン自体UIの分離を目的としているため、１つのファイルが独立し、再利用できます。
しかし、独立しすぎている要素は若干再利用しずらい。


```jsx:atomic/Emphasis.tsx(参照される)
interface Props {
  label: string;
  style: string;
}
const Emphasis = ({ label, style }: Props) => {
  return <em className={style}>{label}</em>;
};

export default Emphasis;
```

```jsx:(参照する)
mport Emphasis from "../atom/Emphasis";

return (
    <p className="text-gray-600">
        {/* <em>{article.author}</em>の方が使いやすいかも？ */}
        By <Emphasis label={article.author} style="" />
    </p>
)
```



### 単一責任の原則
評価は５。

まさに１つのコンポーネントは１つの役割しか果たしていません。
Atoms、Molecules、Organisms、Templates、Pagesのディレクトリごとに役割が分けられるため、要素の役割も明瞭です。


Organismsの例（１つのセクションを表示する）
```jsx:organisms/Section.tsx
import { ReactNode } from "react";
import Header3 from "../atom/Header3";

interface Props {
  title: string;
  children: ReactNode;
}
// １つのセクション要素として、見出しと子要素を描画する
const Section = ({ title, children }: Props) => {
  return (
    <section className="container mx-auto mt-10">
      // atomから持ってきた見出しを描画
      <Header3
        label={title}
        style="text-center text-white text-3xl font-bold"
      />
       // templateから受け取ったchildren要素をそのまま描画
       //　　ここで加工しない
      {children}
    </section>
  );
};

export default Section;
```

## コードの見やすさ
評価は３。

１ファイルのコード量が少ないのがGood:thumbsup:
特にOrganisms、Templatesは実装したオリジナルの要素を多く参照するため、パッと見て何がしたいのか理解に時間がかかるのはマイナス。
間をとって３にしました。

## 実装しやすいか	
評価は２。

- この要素はAtomsか？Moleculesか？とどのディレクトリにするか悩む
- ファイル数が多いため命名を考えるのが面倒
- アルファベット順にファイルが並ぶため、pagesとtemplatesが逆になるのが気持ち悪い

![スクリーンショット 2022-12-07 21.47.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650886/03637421-b5b2-5dc2-f794-2103686ff8cd.png)


ただ慣れるとすぐに分けられるようになる。



## LighthouseによるWEB評価
LighthouseはサイトのパフォーマンスやSEO評価をしてくれるGoogleのツールです。

**AtomicデザインのWEBサイト**
![スクリーンショット 2022-12-05 21.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650886/f0579ed9-068d-f840-7d98-8db3cc7659f9.png)

**ディレクトリ分けしないWEBサイト**
![スクリーンショット 2022-12-05 21.15.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1650886/4aa703b1-dd27-e1f3-99ad-e57ffec12cd9.png)

- Performance
    - サイト内のスピードに関する評価
- Accessibility
    - サイトの訪問者および、検索エンジンのロボットに対して最適な作りになっているか
- Best Practices
    - サイトをスクロールする際のパフォーマンス
- SEO
    - 検索結果のランキングに影響する項目

**Accessibilityが若干高い。**
１つのファイルに全部書くよりファイルを分けた方がレンダリングが最適化されて数値が上がったのかもしれません。詳しくないので原因がわかったら追記します。


さらにアクセシビリティを上げたい場合は公式の「アクセシビリティ」を参照すると良さげです。
https://ja.reactjs.org/docs/accessibility.html


## まとめ

- AtomicデザインはReactの思想に沿ったディレクトリ分けと思われる
- 特にReactが推奨する単一責任の原則とAtomicデザインは相性がいい
- ディレクトリ分けには明確な決まりがなく、慣れや明確なルール決めが必要

## 結論
Atomicデザインをやったことがある人がメンバーにいたら有力なディレクトリ構成になる