Next.js App Routerにおける筆者のBad Practiceを振り返る
はじめに
筆者はもともとReactをメインで利用していたが、Next.js App Routerを利用することになった。
その際にやってしまった初期のBad Practiceを振り返りたい。
あの頃の私をとっちめてやりたい。今にいたるまでの私が改善することになった。
バージョンは以下。
"next": "^14.2.16",
データ取得(Data Fetch)をuseEffect内部で行う✖
これは代表的なBad Practiceだ。
Next.js App RouterはReact Server Components(以下、RSC)を基本としており、データ取得についてもRSCにて取得することを想定している。
可能な限り、useEffectは減らそう。useEffectを使うのは最終手段だ。
RSCでのGET MethodのFetchであれば、多重化排除(Request Memoization)を行ってくれるので、メタデータでのData FetchとページのData Fetchの重複に怯える必要はない(もちろん確認は必要だが)。
多重化排除(Request Memoization)はFetch Cacheをno-storeにしても効いてくれる。なんてありがたい。
ページレンダリングコストを削減するうえで、重要な意識となる。
Server ComponentからClient Componentへユーザには隠匿したい情報を渡す✖
これは、Next.js App Routerがどのようにページをレンダリングしているかに対して理解が必要となる。
Server Componentはサーバーサイドでレンダリングが完結するが、Client Componentはサーバーサイドでプリレンダリングされたのち、ブラウザ側(クライアントサイド)でレンダリングされる。つまり、通信が発生し、引数に渡した情報はネットワークに載ってしまう。
したがって、Server ComponentでData Fetchした情報を丸々Client Componentに渡すと、場合によっては情報が流出する。使う情報のみをClient Componentに渡すべきだ。手打ちの型宣言をしたくないという場合には、Omitを利用しよう。
https://typescriptbook.jp/reference/type-reuse/utility-types/omit
私が曖昧な部分であることがわかったので、イメージだけ記載します。
サブタイプ貫通は今後の課題とさせてください。
ESLintのreact/jsx-props-no-spreadingを有効にすべきですね。
しかし、私もスプリット構文での引数渡しは利用するので、本来は型厳密にできてほしいが。2025/02/09追記:
上記で解決しました。Client-side Router Cacheを考慮せずにページ遷移する✖
これは、情報更新が可能なページを作成するときに対面する問題だ。
ページ遷移時にRouter Cacheが残っており、古いページが表示されてしまうことになる。
Next.js 15ではキャッシュ保持時間を開発者側で操作することが可能だが、Next.js 14ではexperimentalである(筆者は設定すべきと考えているが)。
暫定対応としてrouter.push()後にrouter.refresh()をしよう。
環境変数の優先順位を意識しないで設定する✖
Next.jsの環境変数には優先順位がある。上記順で優先される。
process.env
.env.$(NODE_ENV).local
.env.local (Not checked when NODE_ENV is test.)
.env.$(NODE_ENV)
.env
これを知らないと、ステージング環境に開発環境の環境変数がお邪魔することになる。恐ろしい。
env.localはgitignoreに入れよう。急いで。今すぐに。
ドキュメントを読まないで、記事サイトを参考にする✖
必要なことはドキュメントか、GitHubのIssueに書いてある。それを読んだうえで、記事サイトや個人サイトを参考にしよう。Next.jsは機能が多い。まずはドキュメントで概略をつかもう。そして、私の言っていることを信じるな!(本当は実装されているコードを信じるべきだ)
Reactの展望を追わない✖
Reactの機能として新たに実装されるものは、Next.jsで利用されるといって良い。Server Action,Server Componentの概念ももとはReact由来だ。本当に困ったときは、Reactのドキュメントを見ると良いことが書いてある。
とか。Reactのバージョンアップや思想を追うとNext.jsの向かう方向がなんとなくわかる。
useフックとSuspenseの組み合わせはとても面白い。
背景のないオレオレアーキテクチャを採用する✖
業務でのプロダクトなのだから、採用に至った背景、基準を設けるべきだ。
参画する人数、機能数、技量。保守性。考えることは大きい。
オレオレであることは仕方がないが、説明はできるようにしよう。
コロケーション配置にするか、しないか。
ディレクトリ設計は奥が深い。私も格闘中だ。
appディレクトリの構造変更を考えない✖
appディレクトリはNext.jsのファイルルーティング機能を担っている。
ここに構造変更が入ると、ルーティングへの影響を考慮しなくてはいけない。
なので奥手になりがちだが、可読性や集合を意識したい。
そういう場合はRoute Groupsを利用しよう。layout.tsxを継承させたくない場合にも有効だ。
終わりに
これからNext.jsを学ぶ方々が同じ轍を踏まないことを願う。
Discussion