Segment の規約ファイル
Segmentのディレクトリには、page.tsxとlayout.tsxというファイルの他にも、下記のような名前の決められた規約ファイルを配置できます。
loading.tsxnot-found.tsxerror.tsxroute.tsxtemplate.tsxdefault.tsx
このコースでは、loading.tsx、not-found.tsx、error.tsxのみを扱います。
他のファイルについては、一通りコースが終わった後に一つずつ押さえていけば良いでしょう。
loading.tsx
loading.tsxは、データの取得中に表示するコンポーネントを定義するファイルです。
一般的に API からデータを取得するには時間がかかります。その間にユーザーには何かしらのフィードバックを表示する必要があります。
前の章で、profile/settingsページに API 取得のコードを書いたので、loading.tsxを追加して挙動を確認してみましょう。
export default function SettingsLoading() {
return (
<div className="flex h-screen items-center justify-center">
<h1>データ取得中...</h1>
</div>
);
}
キャッシュを無効にしたいので、fetchの第二引数にcache: "no-cache"を指定してください。
async function getData(): Promise<DogPicture> {
const res = await fetch("https://dog.ceo/api/breeds/image/random", {
cache: "no-cache",
});
return res.json();
}
リロードすると、犬の画像が表示される前に「データ取得中...」と表示されることが確認できます。
このように、loading.tsxを使うことで、データ取得中に表示する画面を簡単に作成することができます。
not-found.tsx
not-found.tsxは、ページが見つからなかった場合に表示するコンポーネントを定義するファイルです。
profile/[id]ディレクトリに not-found.tsxを作成し、以下のコードを追加してください。
export default function NotFound() {
return (
<div className="flex h-screen items-center justify-center">
<h1>404:指定のidは存在しません。</h1>
</div>
);
}
not foundを表示するためには、page.tsxから notFound関数を呼ぶ必要があります。
profile/[id]/page.tsxに以下のコードを追加してください。
import { notFound } from "next";
type Props = {
params: {
id: string;
};
};
export default function Profile({ params }: Props) {
// 0の場合は not found を表示
if (params.id === "0") {
notFound();
}
return <h1>プロフィールページ: {params.id}</h1>;
}
http://localhost:3000/profile/0 にアクセスすると、404:指定のidは存在しません。と表示されることが確認できます。
error.tsx
error.tsxは、エラーが発生した場合に表示するコンポーネントを定義するファイルです。
profile/settingsページにエラーを発生させるために、fetchの URL を間違ったものに変更してください。
async function getData(): Promise<DogPicture> {
const res = await fetch("https://dog.ceo/api/breeds/image/random2", {
cache: "no-cache",
});
if (!res.ok) {
throw new Error("エラーが発生しました");
}
return res.json();
}
そして、profile/settingsディレクトリに error.tsxを作成し、以下のコードを追加してください。
"use client";
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h1>エラー</h1>
<pre>{error.message}</pre>
<button onClick={reset}>リロード</button>
</div>
);
}
error.tsxは他のファイルと違い、"use client"を記述して、Client Componentとして定義する必要があります。引数の型定義が少し複雑になっていますが、基本的にはコピペしてそのまま使えば大丈夫です。
http://localhost:3000/profile/settings にアクセスすると、エラーと表示され、リロードボタンが表示されることが確認できます。