🕌

getStaticPropsとgetStaticPathの使い方と型指定

2023/06/16に公開

はじめに

Next.js で動的ページや外部とのデータ連携する際に必須な
getStaticPropsgetStaticPathの使用方法をまとめてみました。
間違っている箇所がありましたらご指摘いただけると嬉しいです。

getStaticProps

そもそもgetStaticPropsとは
Next.js で静的なページの作成に使用され、
getStaticProps を使うと、
ビルド時にデータを取得してユーザーが web ページに
アクセスする前に HTML を構成してくれます。
主に外部の API にアクセスする際に使用されます。

getStaticPath

こちらはダイナミックルーティングを実装したい時などに
使用されます。
例えば、ブログの記事ページなどで使用され、
getStaticPathでブログの各記事に対してパスを作成し、
getStaticPropsを使用することにより
各記事のデータを取得することができます。

使用方法

今回は jsonplaceholde を使って
データを取得する例で考えていきます。

まずは src フォルダの中に lib フォルダを作成し、
その中にapi.tsファイルを作成します。

データを取得するための関数を作成します。

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を使用して使用して一覧ページの
事前レンダリングを行います。

home/index.tsx
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 ページ内はこのように表示されます。
Postsページ内

続いてダイナミックルーターを用いて記事のページを作成します。

pages フォルダの中に[id]フォルダを作成し、
その中にindex.tsxを作成します。

[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,
    },
  };
};


細かく解説していきます。

index.tsx
const Post: React.FC<PostProps> = ({ post }) => {
  return (
    <>
      <h2>{post.title}</h2>
      <p>{post.body}</p>
    </>
  );
};

こちらは関数 Post にプロパティ post を受け取り
記事のタイトルと本文を取得しています。

index.tsx
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 ページを表示するようにします。

index.tsx
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はビルド時に動的なパスを持つページを
静的に事前生成剃る方法を定義できます。

ブログサイトを制作したりして、
getStaticPropsgetStaticPathを使用して
これからも勉強していきます!

Discussion