はじめに
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
私見による評価
Reactの設計原則に則っているか
Reactの思想に近いディレクトリ構成であればベストプラクティスのはず、ということでReactの設計原則に関連する3項目を評価対象にしました。
-
宣言的なView
- 関連するコンポーネントのみ更新、描画する
- 無駄に再レンダリングしない
-
コンポーネント
- UIは独立し、再利用できる部品であるか
-
単一責任の原則
- ひとつのコンポーネントはひとつの役割だけをするべき
宣言的なView
評価は3。
Atomicデザインは要素を細かく分解するため、要素数が多いです。
そのため、要素ごとに再レンダリングを抑えるコードを書けば、再レンダリングを抑えることができます。
反面、関連する要素が多い変数が更新された場合の処理も多くなる可能性があります。更新処理が起きたとき、どの要素に影響するのかを考慮するためには、ある程度技量が必要と考えられるので評価を3にしました。
コンポーネント
評価は4。
Atomicデザイン自体UIの分離を目的としているため、1つのファイルが独立し、再利用できます。
しかし、独立しすぎている要素は若干再利用しずらい。
interface Props {
label: string;
style: string;
}
const Emphasis = ({ label, style }: Props) => {
return <em className={style}>{label}</em>;
};
export default Emphasis;
mport Emphasis from "../atom/Emphasis";
return (
<p className="text-gray-600">
{/* <em>{article.author}</em>の方が使いやすいかも? */}
By <Emphasis label={article.author} style="" />
</p>
)
単一責任の原則
評価は5。
まさに1つのコンポーネントは1つの役割しか果たしていません。
Atoms、Molecules、Organisms、Templates、Pagesのディレクトリごとに役割が分けられるため、要素の役割も明瞭です。
Organismsの例(1つのセクションを表示する)
import { ReactNode } from "react";
import Header3 from "../atom/Header3";
interface Props {
title: string;
children: ReactNode;
}
// 1つのセクション要素として、見出しと子要素を描画する
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;
コードの見やすさ
評価は3。
1ファイルのコード量が少ないのがGood
特にOrganisms、Templatesは実装したオリジナルの要素を多く参照するため、パッと見て何がしたいのか理解に時間がかかるのはマイナス。
間をとって3にしました。
実装しやすいか
評価は2。
- この要素はAtomsか?Moleculesか?とどのディレクトリにするか悩む
- ファイル数が多いため命名を考えるのが面倒
- アルファベット順にファイルが並ぶため、pagesとtemplatesが逆になるのが気持ち悪い
ただ慣れるとすぐに分けられるようになる。
LighthouseによるWEB評価
LighthouseはサイトのパフォーマンスやSEO評価をしてくれるGoogleのツールです。
- Performance
- サイト内のスピードに関する評価
- Accessibility
- サイトの訪問者および、検索エンジンのロボットに対して最適な作りになっているか
- Best Practices
- サイトをスクロールする際のパフォーマンス
- SEO
- 検索結果のランキングに影響する項目
Accessibilityが若干高い。
1つのファイルに全部書くよりファイルを分けた方がレンダリングが最適化されて数値が上がったのかもしれません。詳しくないので原因がわかったら追記します。
さらにアクセシビリティを上げたい場合は公式の「アクセシビリティ」を参照すると良さげです。
https://ja.reactjs.org/docs/accessibility.html
まとめ
- AtomicデザインはReactの思想に沿ったディレクトリ分けと思われる
- 特にReactが推奨する単一責任の原則とAtomicデザインは相性がいい
- ディレクトリ分けには明確な決まりがなく、慣れや明確なルール決めが必要
結論
Atomicデザインをやったことがある人がメンバーにいたら有力なディレクトリ構成になる