web-dev-qa-db-ja.com

ルートパラメータに基づくサーバー側の動的ページのレンダリング

私はNext.jsから始めて、ドキュメントを調べた後、以下に示すようにcodeメソッド内のルートパラメータgetStaticPathsを取得する方法を理解できません!?。 codeは、どのような手段によっても事前に知られていないため、何でもかまいません。

APIを呼び出して、コンポーネント内でuseEffectを使用してデータを取得したくありません。

ファイル:pages/post/[code] .js

import React from 'react';
import apiCall from 'api/something';

export default ({post}) => {
     return <>
        render components here based on prop `post`
    </>
}

export async function getStaticPaths() {
    // How to get [code] from the route here, which can be used below?
    return { 
        paths: // NEED [code] HERE from current route,
        fallback: false
    }
} 

export async function getStaticProps(ctx) {
    return {
        props: { 
         // [ctx.code] resolved from current route with the help of getStaticPaths,
         post: apiCall(ctx.code) 
        }
    }
}

私はgetServerSidePropsを試しましたが、うまくいきました:

export const getServerSideProps = async (ctx) => {
    return {
        props: {
            post: await apiCall(ctx.query.code)
        }
    };
};

しかし、私がやると失敗しますnext export説明:

getServerSidePropsのあるページはエクスポートできません。詳細はこちら: https://err.sh/next.js/gssp-export

このエラーについてさらに調査した後 私はこの解決策を見つけました 、これは私のアプリがHerokuでホストされているため、私には実行できません。

私は、ルートパラメータcodeに基づいて、データとともにHTMLをサーバー側でレンダリングしようとしています。しかし、今はそうすることができません。

2
boop_the_snoot

関数getStaticPathsの目的は、ビルド時に静的HTMLがレンダリングされるパスのリストを生成することです。たとえば、10個の投稿のリストの場合、投稿のIDがわかっていれば、事前に10個のposts/[id]ルートを生成できます。

getStaticPathsが動的ルートとどのように連携するかについて詳しく説明します。

動的ルート/posts/[postId]があるとします。静的生成を使用する場合は、postIdをルートパラメータとして含むパスのリストを生成する必要があり、返される各パスについて、関数getStaticPropsが呼び出されてクエリを実行しますビルド時のデータ。例、

// for /post/[postId]

export const getStaticPaths = async () => {
  // if you know all the postId ahead of time

  const paths = [
     { params: { postId: '1234' } },  // keep in mind postId has to be a string
     { params: { postId: '3792' } },
     { params: { postId: '1749' } },
  ]

  return {
    paths,
    fallback: false // we are disabling fallback because we know all the paths ahead of time
  }
}

// for each path returned getStaticProps will be called at build time
export const getStaticProps = async (context) => {
   // you have access to the postId params that you returns from
   // getStaticPaths here
   const postId = context.params.postId 

   // now you can query the data from postId and return as props

   return {
     props: // queried data
   }
}

関数fallback nextjsから返されないルートパスのfalsegetStaticPaths anyに設定されている場合は、単に404エラーページが表示されます。

fallback: trueを使用して、事前に不明なルートパラメータの静的ページを生成する方法

投稿の一部のpostIdがわかっていて、postsのデータがあまり頻繁に変更されない場合は、fallbackプロパティをtrueに設定してページを生成することを選択できます。これにより、返されないパスのページのフォールバックバージョンが表示されます関数getStaticPathsから。そして、ページの要求に応じて、nextjsはgetStaticPropsを呼び出し、ブラウザーでページをレンダリングするために使用されるJSONとしてデータを送信します。例、

// for /post/[postId]
export const getStaticPaths = async () => {
   // you can get how many ever postIds are know ahead of time 
   // and return as paths with fallback set to true
   const posts = // queried data from db or fetched from remote API

   const paths = posts.map(post => { params:{ postId: post.id.toString() }})

   return {
      paths,
      fallback: true
   }

}

// in your page Component check for fallback and render a loading indicator
import { useRouter } from 'next/router';

const MyPage = (props) => {
  // before you do anything
  const router = useRouter();

  if (router.isFallback) {
    return <div>Loading....</div>
  }

  // rest of your page logic

}

データが非常に動的な場合、30分または1時間程度ごとに変更するとします。リクエストごとにデータをfetchするサーバー側レンダリングの使用を選択できますが、TTFB(最初のバイトまでの時間)は高くなります。例えば、

// for /post/[postId]
export const getServerSideProps = async (context) => {

  // you also have access to the param postId from the context
  const postId = context.params.postId

  // query the data based on the postId and return as props
  return {
    props: // queried data
  }  

}

getServerSidePropsを使用することを選択した場合、関数はリクエストごとに呼び出されるため、最初のバイトまでの時間が長くなることに注意してください。

ユースケースによっては、nextjsチームのswrを使用してクライアント側のデータフェッチで静的生成を使用することもできます repo link

2
subashMahapatra

私が理解しているように、ビルド時に動的ルートを静的に生成する必要があります。

そのためには、すべてのcodesを指定して、生成するページをNext.jsに通知する必要があります。

export async function getStaticPaths() {
    // you don't need here a code from current route
    // but you need to specify all known post codes
    return { 
        paths: [
          { params: { code: '1' } },
          { params: { code: '2' } },
          { params: { code: '3' } },
        ]
        fallback: false
    }
}

投稿を変更するたびにアプリを再構築する必要があります。

毎回プロジェクトを再ビルドしたくない場合は、getServerSidePropsを使用します。その後、データはリクエスト時にフェッチされます。 Node.jsサーバーが必要なため、exportできません。

0
Nikolai Kiselev