Next.jsの勉強会 vol.6 ファイル分割(components・data・types)
今回学ぶこと
Next.jsでページを作っていると、1つのpage.tsxにコードが増えていく。
最初は1ファイルで書く方が分かりやすいが、コンポーネント、データ、型が混ざると読みにくくなる。そこで、役割ごとにファイルを分ける。
src/components
UI部品を置く
src/data
表示用データを置く
src/types
型定義を置くコンポーネントを別ファイルに移す
もともとServiceCardはsrc/app/page.tsxの中に書いていた。
function ServiceCard({ title, description, price }: ServiceCardProps) {
return (
<article className="border border-zinc-200 bg-white p-6 shadow-sm">
<h3 className="text-xl font-semibold">{title}</h3>
<p className="mt-4 leading-7 text-zinc-600">{description}</p>
<p className="mt-6 border-t border-zinc-200 pt-4 text-sm font-semibold text-zinc-950">
{price}
</p>
</article>
);
}これを次のファイルに移した。
src/components/service-card.tsxexportで外から使えるようにする
別ファイルに移したコンポーネントは、他のファイルから読み込めるようにexportする。
export function ServiceCard({ title, description, price }: ServiceCardProps) {
return (
<article className="border border-zinc-200 bg-white p-6 shadow-sm">
<h3 className="text-xl font-semibold">{title}</h3>
<p className="mt-4 leading-7 text-zinc-600">{description}</p>
<p className="mt-6 border-t border-zinc-200 pt-4 text-sm font-semibold text-zinc-950">
{price}
</p>
</article>
);
}exportを付けることで、別ファイルからServiceCardをimportできる。
importで読み込む
src/app/page.tsxでは、切り出したServiceCardを読み込む。
import { ServiceCard } from "@/components/service-card";この@/components/service-cardは、src/components/service-card.tsxを指している。
このプロジェクトでは@/がsrc/を表す設定になっているためである。
@/components/service-card
↓
src/components/service-card.tsxなぜ分けるのか
ファイルを分けると、page.tsxの役割が分かりやすくなる。
page.tsxは、ページ全体の構成を担当する。
ServiceCardは、サービスカード1枚の見た目を担当する。
page.tsx
ページ全体の構成
service-card.tsx
カードUIの部品このように役割を分けることで、あとから修正する場所を見つけやすくなる。
データを別ファイルに移す
ServiceCardを切り出したあと、サービス一覧のデータもpage.tsxから分離した。
src/data/services.tsこのファイルには、サービス一覧として表示するデータを置く。
type Service = {
title: string;
description: string;
price: string;
};
export const services: Service[] = [
{
title: "コーポレートサイト制作",
description:
"会社の強みや問い合わせ導線を整理して、信頼感のあるWebサイトに仕上げます。",
price: "80万円から",
},
];export const servicesと書くことで、他のファイルからサービスデータを読み込める。
page.tsxでデータを読み込む
page.tsxでは、servicesをimportして使う。
import { services } from "@/data/services";これにより、page.tsxからデータ定義が消え、ページ本体が読みやすくなった。
page.tsx
ページ全体の構成
service-card.tsx
カードUI
services.ts
サービスの表示データコンポーネントとデータを分けることで、UIを直したいときはcomponents、表示内容を直したいときはdataを見る、という判断がしやすくなる。
型を別ファイルに移す
Lesson40では、Service型をsrc/types/service.tsに移した。
src/types/service.ts型定義は次のように書く。
export type Service = {
title: string;
description: string;
price: string;
};export typeを使うことで、他のファイルからService型を読み込める。
dataファイルで型を読み込む
src/data/services.tsでは、Service型をimport typeで読み込む。
import type { Service } from "@/types/service";import typeは、型だけを読み込むための書き方である。
実行時に使う値ではなく、TypeScriptの型チェックにだけ使う。
その上で、services配列に型を付ける。
export const services: Service[] = [
{
title: "コーポレートサイト制作",
description:
"会社の強みや問い合わせ導線を整理して、信頼感のあるWebサイトに仕上げます。",
price: "80万円から",
},
];これにより、services配列の各データはService型に合っている必要がある。
例えばpriceを書き忘れると、TypeScriptがエラーとして教えてくれる。
components・data・typesの役割
ここまでで、ファイルの役割は次のように分かれた。
src/components/service-card.tsx
カードUI
src/data/services.ts
サービスの表示データ
src/types/service.ts
サービスデータの型役割を分けることで、コードの見通しがよくなる。
UIを直すならcomponents、表示内容を直すならdata、データの形を直すならtypesを見る、という判断ができる。