はじめに
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
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: { id: string }
}
// 実際のページコンポーネント
const PostPage: React.FC<PostPageProps> = ({ params }) => {
// paramsから渡されたidを使って、該当する投稿を探す
const post = posts.find((p) => p.id === params.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()
への移行は、最初は戸惑うかもしれません。でも、使ってみると「あ、これ簡単じゃん!」と思えるはずです。