getStaticPropsとgetStaticPathの使い方と型指定
はじめに
Next.js で動的ページや外部とのデータ連携する際に必須な
getStaticProps
とgetStaticPath
の使用方法をまとめてみました。
間違っている箇所がありましたらご指摘いただけると嬉しいです。
getStaticProps
そもそもgetStaticProps
とは
Next.js で静的なページの作成に使用され、
getStaticProps
を使うと、
ビルド時にデータを取得してユーザーが web ページに
アクセスする前に HTML を構成してくれます。
主に外部の API にアクセスする際に使用されます。
getStaticPath
こちらはダイナミックルーティングを実装したい時などに
使用されます。
例えば、ブログの記事ページなどで使用され、
getStaticPath
でブログの各記事に対してパスを作成し、
getStaticProps
を使用することにより
各記事のデータを取得することができます。
使用方法
今回は jsonplaceholde を使って
データを取得する例で考えていきます。
まずは src フォルダの中に lib フォルダを作成し、
その中にapi.ts
ファイルを作成します。
データを取得するための関数を作成します。
const fetchPostData = async() => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
return data;
}
fetchPostData
という関数を非同期処理で作成します。
fetch を用いて URL を指定し、JSON 形式のデータを非同期に取得します。
非同期処理を行うことにより、ネットワークリクエストの完了を
待つ間に他の処理を実行でき、レスポンス性が向上します。
次にgetStaticProps
を使用して使用して一覧ページの
事前レンダリングを行います。
import { fetchPostData } from "@/lib/api";
import Link from "next/link";
type Post = {
id: number;
title: string;
};
type HomeProps = {
posts: Post[];
};
const Home: React.FC<HomeProps> = ({ posts }) => {
return (
<div>
<ul>
{posts.map((post: any) => (
<li key={post.id}>
<Link href={`/${post.id}`}>
<h2>{post.title}</h2>
</Link>
</li>
))}
</ul>
</div>
);
};
export default Home;
export const getStaticProps = async () => {
const posts = await fetchPostData();
return {
props: {
posts,
},
};
};
getStaticProps
を用いて
先程の fetchPostData 関数を呼び出し
返り値として props オブジェクトの posts プロパティにセットします。
これにより posts データをページコンポーネント内で
props.posts として使用することができます。
PostPage 関数内で引数を先程のposts
を指定し、
map 関数で繰り返しpost.title
を表示させています。
Posts ページ内はこのように表示されます。
続いてダイナミックルーターを用いて記事のページを作成します。
pages フォルダの中に[id]
フォルダを作成し、
その中にindex.tsx
を作成します。
import { fetchPostData } from "@/lib/api";
import React from "react";
type Post = {
id: number;
title: string;
body: string;
};
type PostProps = {
post: Post;
};
type Params = {
id: string;
};
const Post: React.FC<PostProps> = ({ post }) => {
return (
<>
<h2>{post.title}</h2>
<p>{post.body}</p>
</>
);
};
export default Post;
export const getStaticPaths = async () => {
const posts: Post[] = await fetchPostData();
const paths = posts.map((post) => ({
params: {
id: post.id.toString(),
},
}));
return {
paths,
fallback: false,
};
};
export const getStaticProps = async ({ params }: { params: Params }) => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.id}`
);
const post = await res.json();
return {
props: {
post,
},
};
};
細かく解説していきます。
const Post: React.FC<PostProps> = ({ post }) => {
return (
<>
<h2>{post.title}</h2>
<p>{post.body}</p>
</>
);
};
こちらは関数 Post にプロパティ post を受け取り
記事のタイトルと本文を取得しています。
export const getStaticPaths = async () => {
const posts: Post[] = await fetchPostData();
const paths = posts.map((post) => ({
params: {
id: post.id.toString(),
},
}));
return {
paths,
fallback: false,
};
};
getStaticPaths
を用いて静的なパスを入手しています。
api.ts で作成した fetchPostData を呼び出して posts という関数に指定しています。
posts.map()
メソッドを使用して投稿データをループ処理します。
各投稿に対して params を用いて post.id を文字列として指定します。
最後にpaths
の配列とfallback
を返します。
fallback を false に指定します。
これは未定義のパスに対しては 404 ページを表示するようにします。
export const getStaticProps = async ({ params }: { params: Params }) => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.id}`
);
const post = await res.json();
return {
props: {
post,
},
};
};
getStaticProps
関数で、指定されたパスのデータを取得します。
引数に params を指定し、
fetch 関数を使用して URL に GET リクエスト送信しデータを取得します。
res.json()を使用して。JSON 形式に変換し、
post プロパティを返します。
これにより、静的な HTML を生成し、その id に対応する
データを取得します。
これで先程のタイトルをクリックしたら
各記事を表示することができます!
最後に
最後までお読みいただきありがとうございました!
ざっくりまとめると
getStaticProps
は外部の API にアクセスする際に使用され、
getStaticPath
はビルド時に動的なパスを持つページを
静的に事前生成剃る方法を定義できます。
ブログサイトを制作したりして、
getStaticProps
とgetStaticPath
を使用して
これからも勉強していきます!
Discussion