基于路由参数的服务器端渲染动态页面

时间:2020-05-26 15:34:53

标签: javascript reactjs next.js server-side-rendering

我从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

在进一步研究此错误I found this solution后,由于我的应用程序托管在Heroku上,因此这对我来说不可行。

我正在尝试基于路由参数code在服务器端呈现html和数据。但现在无法这样做。

2 个答案:

答案 0 :(得分:3)

函数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设置为false,对于任何未从函数getStaticPaths返回的路由路径,nextjs只会显示一个404错误页面。

如何使用fallback: true为提前未知的路由参数生成静态页面

如果您知道某些postId帖子,并且posts的数据很少更改,则可以选择生成fallback属性设置为{{1 }},它将显示页面的后备版本,而不是从函数true返回的路径。并且在请求页面时,nextjs将调用getStaticPaths并将数据作为JSON发送,该数据将用于在浏览器中呈现页面。 例子,

getStaticProps

如果您的数据非常动态,可以说每30分钟或一小时左右更改一次。您可以选择使用服务器端渲染,该渲染将根据每个请求// 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 } 进行数据处理,但是TTFB(到第一个字节的时间)会更高。例如,

fetch

请记住,如果您选择与// 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 } } 一起使用,该函数将基于每个请求被调用,因此到第一个字节的时间会更长。

根据用例,您还可以使用nextjs团队repo linkgetServerSideProps进行客户端数据的静态生成。

答案 1 :(得分:0)

据我了解,您想在构建时静态生成动态路由。

为此,您需要通过指定所有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。然后,将在请求时获取数据。您不能export,因为它需要Node.js服务器。

相关问题