getStaticPathsに関連

19479 ワード

getStaticPaths


以前,動的ルーティングが要求されるたびに生成されるページをテストしたが,構築時に静的ページを作成する方法もあった.
api pathパスによっては、コンテンツがあまり変更されていないページにデータが役立つ場合があります./post/2getStaticPathsおよびgetStaticPropsを使用すればよい.これは、構築時にgetStaticPathsを使用して外部データの動的パスのリストを受信し、getStaticPropsに渡してStaticPageを作成する方法である.

コードは次のとおりです.
// pages/post/[id].tsx

export async function getStaticPaths() {
  const res = await fetch(`${JSONPLACEHOLDER_URL}/posts`);
  const allPostsData = await res.json();

  const paths = allPostsData.map((post: PostProps) => ({
    params: {
      id: post.id.toString(),
    },
  }));

  return {
    paths,
    fallback: false,
  };
}

export async function getStaticProps({ params }: any) {
  const res = await fetch(`${JSONPLACEHOLDER_URL}/posts/${params.id}`);
  const postData = await res.json();

  return {
    props: {
      postData,
    },
  };
}
最初は、次のようにパスを渡すために、idは文字列形式で提供する必要があるようです.
const paths = allPostsData.map((post: PostProps) => ({
  params: {
    id: post.id,
  },
}));
(ここでidは動的ルーティングのfilenameに依存し、私の場合はpages/post/[id].tsxなのでidで記入します.)

作成時に静的ページを作成する


ビルド時にデータをインポートして、予めStatic Pageを生成していることがわかります.
△ここに100ページあるのは、getStaticPathsが100個のIDを取得したからです.

fallbackの役割


上のコードからgetStaticPathsのfallbackが表示されます.ロールは次のとおりです.
まずexpressで以下のようにデータを返すapiを簡単に作成した.
const data = [
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },
  {
    "userId": 1,
    "id": 3,
    "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
    "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
  }
];  


app.get('/posts', (req, res) => {
  return res.json(data);
});

app.get('/posts/:id', function(req, res, next) {
  const { id } = req.params;
  let post = data.filter(u => u.id == id )[0];
  
  if(!post) post = {};
  
  return res.json(post);
});

app.listen(port, function () {
  console.log(`🔥Server on! http://localhost:${port}`);
});
これでbuildは3つのStatic Pageを作成しurlを変更して実行し、3つのpostがよくロードされていることがわかります.

fallback: false


ここで、バックエンドにデータ変更が発生した場合、4番目の記事が表示されますが、만들어두지 않았던 4번째 포스트로 url로 이동はどうなりますか?
このときの役割はfallbackです.
fallbackがfalseの場合、結果は次の404ページに表示されます.

fallback: true


次にfallbackをtrueに変更します.
また、構築中にエラーが発生しました.

よく読むとtypeErrorが次のコードからundefinedに移動したためにエラーが発生していることがわかります.
const { userId, title, body } = postData;
この問題を解決するためにrenderセクションでisCallback値をチェックした.
function PostDetail({ postData }: Props) {
  const { isFallback } = useRouter();


  // If the page is not yet generated, this will be displayed
  // initially until getStaticProps() finishes running
  if (isFallback) {
    return <div>Loading...</div>;
  }

  const { userId, title, body } = postData;

  return (
    <ul>
      <Post userId={userId} title={title} body={body} />
    </ul>
  );
これでよく構築され、最初は3つ生成されましたが、ここでurlを4番目のpostに移動すると、新しいデータを取得してページを作成しながらページを表示できます.
http://localhost:3000/post/4を打った時点で、Static Pageが作成された.
まずページをレンダリングします(isCalback:true)Loading...この表示後、fetch終了時に(isCallback:false)となり、新しいデータが表示されます.そのため、上で構築中にエラーが発生する可能性があります.


新しい動的ルーティングのためにisFallbackを使用してStatic Pageを作成する場合...表示したくない場合は、fallback: 'blocking'オプションを使用できます.△SSRのように働きます.

Reference

  • https://nextjs.org/docs/api-reference/data-fetching/get-static-paths