最近の自分のReactの書き方・進め方
最近の自分の React を用いたコーディング方法と、プロジェクト設計をなんとなく書いていこうと思います。
前提
一応以下の環境を前提で話を進めます。
- Next.js
- CSS Modules
- TypeScript
Create React App でもほぼ大差ないと思います。
ファイル・フォルダー構成
Next.js の場合は公式ドキュメントに沿ってsrc
フォルダーを作成し、src
以下は大体以下のような感じに収まります。
src
├── components
│ ├── atoms
│ ├── molecules
│ ├── organisms
│ └── templates
├── contexts
├── hooks
├── libs
├── pages
└── styles
上記以外のフォルダーを切ることはほとんどありません。
一応各フォルダーについてざっくり説明すると。
components
presentational components を切るフォルダーになります。
Atomic Design を使用しない場合、 components
以下はネスト 1 でコンポーネントを切ることがほとんどです。
直下にコンポーネントファイルを格納するフォルダーは Upper Camel Case で、それ以外は Lower Camel Case で統一します。
contexts
コンテキスト を使用する場合のみ作成します。
○○Context
というフォルダー名で統一します。
hooks
カスタム hooks を使用する場合のみ作成します。
use○○
というフォルダー名で統一します。
libs
サーバー側のみ、またはサーバーとフロントで共通の処理が必要な場合に作成します。
pages
container components を切るフォルダーになります。
フォルダー名は Lower Camel Case で統一します。
styles
グローバルなスタイルファイルを切るフォルダーになります。
コンポーネントの書き方
presentational components と container components を問わず以下の書き方をしています。
import React, { ReactNode } from "react";
import styles from "./styles.module.scss";
export type HogeProps = {
children: ReactNode;
};
function Hoge({ children }: HogeProps): JSX.Element {
return <div className={styles.wrapper}>{children}</div>;
}
export default Hoge;
決め事としては以下のとおりです。
アロー関数を使用しない
型周りが人によって書きっぷりが変わるのと、return 文を省略したり書いたりが面倒なので、それならばと。
React の公式も function で書いているケースが結構あるので、問題ないかなと。
ただし container components において NextPage
が使用できないのは気になってる。
公式ドキュメント に言及がないので、問題ないのかな?
props の型は export する
公開情報なので当たり前です。
使用の有無は関係ありません。
props の型名はコンポーネント名 + Props
迷わないので。
公式系のドキュメントも大体こうなっている印象です。
default export を使用する
好みの問題だと思いますが、自分は default export 派なのでこう書きます。
つまりコンポーネントファイルは 1 default export と 1 named export で固定されます。
その他
自分がプライベートで開発する際に守っていることをいくつか書き出すと。
共通化はなるべく行わない
フロントエンド開発において、共通化ってあまりしないほうがスムーズに開発できると思っています。
とくにコンポーネント側はともかく、ロジック側について共通化は最低限にすべきです。
コンテキストもカスタム hooks も libs 以下も、結局グローバルな値なわけで。
共通化は手段であって目的ではありません、そこを見失うと共通化が大きく足を引っ張ってしまうかなと。
スタイリングは CSS Modules で
自分はロジックとスタイリングの領域を分けたいタイプなので、CSS Modules が 1 番好きです。
Styled Components も高機能で悪くないのですが、開発・保守ともに難易度は高い印象があります。
CSS Modules であれば公式のサポート内ですし、追加のパッケージもいらないですし、良いことづくめです。
ネストするくらいなら横に広げる
フォルダー設計においてネストを何よりも嫌っているので、なるべく平たい構成にすることを心がけています。
フォルダーをネストさせるメリットがまったくわかっていないのですが、何が良いんですかね?
default export で統一する
型以外についてはすべて default export で統一するようにしています。
1 ファイルにおける意味合いをなるべく厳密にさせたいので、コンポーネントに限らず context もカスタム hooks もすべて default export させます。
そんな感じです、参考になれば幸いです。
GitHub にいくつかリポジトリーを公開していますので、よろしければ。