はじめに
Next.jsを勉強し始めた方、混乱してしまう静的ページのビルド。
経験者は何だそんなことよという内容かもしれませんが、ReactからNextjsまで学習ロードマップを進んだ方はかなり悩むポイントでもあるので、本日はこのテーマで解説していきたいと思います。
getStaticPropsとgetServerSidePropsは廃止されたよ
Next.js 13以降、App RouterというNew Routerの導入により、これまでおなじみだったgetStaticPropsとgetServerSidePropsがなくなりました。「えっ、じゃあどうやって静的生成するの?」ってことで、新しい主役のgenerateStaticParamsの登場です。
新しい主役のgenerateStaticParams()
getStaticPropsの代わりに登場したのがgenerateStaticParams()です。この関数は、動的ルートを持つページの静的生成に使用されます。
他に関連するところを解説しますと、
-
getServerSidePropsとgetStaticPropsの 廃止 -
getStaticPathsはgenerateStaticParamsに変更
今回はこの生き残ったgenerateStaticParamsの解説になるというわけです![]()
そもそもなぜこれらの変更が行われたのか?
これらの変更の背景には、「サーバーコンポーネント」という新しい概念の導入があります。サーバーコンポーネントを理解すると、これらの変更が自然な流れであることがわかります。
サーバーコンポーネントとは?
今回はこの部分は主題ではないので簡単な解説にとどめます。気になる方はこの記事をご覧ください!
メチャクチャ簡単にいうとサーバーコンポーネントは、サーバー上で実行されるReactコンポーネントです。これにより、サーバー側で直接データを取得したり、処理を行ったりすることができます。
変更の理由
-
直接非同期処理が可能に:
サーバーコンポーネント内で直接非同期処理を書けるようになったので、getServerSidePropsやgetStaticPropsのような特別な関数を使わなくてもいいよね!ってことですな。まあそりゃそうかと。 -
柔軟性の向上:
generateStaticParamsの導入により、静的生成するページのパラメータをより柔軟に定義できるようになりました。これは特に、動的ルーティングを使用する際に便利です。この部分を解説していきます。
generateStaticParams()って何をするの?
簡単に言うと、「動的なURLを持つページを、事前に静的なHTMLとして生成するための関数」です。
例えば、ブログの記事ページ/posts/[id]があるとします。この[id]部分に入る値を事前に指定することで、ビルド時に静的なページを生成できるということですね。
実際のコードを見てみよう(NextjsとTypeScript使用)
// type.ts
export type Post = {
id: string;
title: string;
content: string;
}
// data.ts
export const posts: Post[] = [
{ id: '1', title: '最初の投稿', content: '内容1' },
{ id: '2', title: '次の投稿', content: '内容2' },
// さらに投稿が続く...
];
// app/posts/[id]/page.tsx
import { Post } from '../../types';
import { posts } from '../../data';
export async function generateStaticParams(): Promise<{ id: string }[]> {
return posts.map((post) => ({
id: post.id,
// 各ポストのidを設定。この { id: post.id } が下記paramsに渡る
}));
}
// ページコンポーネントの型定義
type PostPageProps = {
params: Promise<{ id: string }>
}
// 実際のページコンポーネント
const PostPage = async ({ params }: PostPageProps) => {
// paramsをawaitで解決
const { id } = await params;
// paramsから渡されたidを使って、該当する投稿を探す
const post = posts.find((p) => p.id === id);
// 投稿が見つからない場合のエラーハンドリング
if (!post) {
return <div>ポストが見つかりません。</div>;
}
// 投稿の内容を表示
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
export default PostPage;
コードの詳細な解説
generateStaticParams()
-
export async function generateStaticParams(): Promise<{ id: string }[]>- この関数がキモです。非同期関数として定義されており、静的生成するページのパラメータを返します。
- 返り値の型を明示的に指定しています。
{ id: string }[]という形式の配列を返すことを示しています。
-
return posts.map((post) => ({ id: post.id }));- 全ての投稿のIDをマップして返しています。
- これにより、各投稿のIDに対応する静的ページが生成されます。
この方法のポイント
-
generateStaticParamsが返す値に基づいて、ビルド時に静的ページが生成されます。 - 例えば、投稿が3つあれば、
/posts/1、/posts/2、/posts/3という3つの静的ページが生成されます。 - ページコンポーネントは、これらの静的生成されたページ全てで使用されます。
- URLパラメータ(この場合は
id)はparamsオブジェクトを通じてPostPageコンポーネントに渡されます。
まとめ
getStaticPropsからgenerateStaticParams()への移行は、最初は戸惑うかもしれません。でも、使ってみると「あ、これ簡単じゃん!」と思えるはずです。