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

boo*_*oot 4 javascript reactjs server-side-rendering next.js

我从 Next.js 开始,在浏览文档后,我无法弄清楚如何codegetStaticPaths方法中获取路由参数,如下所示!?。code以任何方式事先都不知道,它可以是任何东西。

我不想调用 api 并在组件内部使用 useEffect 获取数据。

文件:页面/帖子/[代码].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) 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我试过getServerSideProps对我有用的:

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

但是当我next export声明时它失败了:

getServerSideProps无法导出的页面。在此处查看更多信息:https : //err.sh/next.js/gssp-export

在进一步调查此错误后,我找到了这个解决方案,这对我来说不可行,因为我的应用程序托管在 Heroku 上。

我正在尝试在服务器端呈现 html 以及基于 route param 的数据code。但现在不能这样做。

sub*_*tra 6

该函数的目的getStaticPaths是生成一个路径列表,在构建时将为其呈现静态 HTML。例如,对于 10 个帖子的列表,posts/[id]如果您知道帖子的 id ,您可以提前生成 10 个路由。

如何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
   }
}
Run Code Online (Sandbox Code Playgroud)

如果fallbackfalse任何未从函数getStaticPathsnextjs返回的路由路径设置为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

}
Run Code Online (Sandbox Code Playgroud)

如果您的数据非常动态,假设每 30 分钟或一小时左右更改一次。您可以选择使用服务器端渲染,这将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
  }  

}
Run Code Online (Sandbox Code Playgroud)

请记住,如果您选择使用getServerSideProps该函数,将在每个请求的基础上调用该函数,因此第一个字节的时间会更长。

根据用例,您还可以使用静态生成和客户端数据获取,使用swr来自 nextjs team repo link