这是我参与「第五届青训营」笔记创作活动的的第 9 天 在next.js中文网中我们知道Next.js 有两种预渲染形式:静态生成和服务器端渲染
静态生成:如果一个页面使用了静态生成,在页面构建时将生成对应的HTML文件,意味着在生产环境中,运行‘next build’时将生成该页面对应的HTML文件,接着,对应的HTML文件将在每个页面发请求时被复用,也可以被CDN缓存。 tips:这里的页面构建分为两个阶段:
解析HTML并解析文档对象模型(DOM) 执行JavaScript脚本 服务端渲染(SSR|动态渲染):如果一个页面使用了服务端渲染,则在每次页面请求时重新去生成HTML文件。 想要在预渲染时获取数据,分为两种情况:
在静态生成预渲染阶段,我们的页面组件需要使用到外部数据【接收参数】,通常使用到Next.js提供的函数:getStaticProps ,而如果咱们的页面使用动态路由,也需要的这个函数:getStaticPaths 。这两个函数都需要从同一文件export并都是async异步函数,都在构建时被调用,并允许咱们在预渲染阶段将获取的数据作为props传递给页面。
在服务端渲染阶段,咱们如果在某个页面需要频繁去更新数据,可以使用getServerSideProps这个函数去获取数据并传递给页面。这个函数也是从同一页面文件export同时也是async异步函数,在每次页面发请求时被调用。
下面咱们来说说这三个函数:
getStaticProps(静态生成):在构建时获取数据。 getStaticPaths(静态生成):指定动态路由以根据数据预渲染页面。 getServerSideProps(服务器端渲染):获取每个请求的数据。 此外,我们将讨论如何在客户端获取数据:
getStaticProps(静态生成):在构建时获取数据
如果从页面export名为 getStaticProps 的异步函数,Next.js 将在构建时使用 getStaticProps 返回的props预渲染此页面。
export async function getStaticProps(context) { return { props: {}, // 将作为props传递给页面组件 } } 接收的形参context为一个对象:
params 包含使用过动态路由页面的路由参数,如果页面文件名称是[name].js,那么params为{name:xxx,xxx:xxx...},它也可以跟getStaticPaths一起使用,后面再说! const {name} = context.params preview 如果页面处于预览模式,则preview为true否则为undefined。这个属性可以在发请求时呈现页面而不是在构建时呈现,可以绕过静态生成预渲染阶段。 previewData 包含 setPreviewData 设置的预览数据 getStaticProps返回一个对象:
props 带有将页面组件接收的props可选对象 revalidate 以秒为单位的可选数量,之后可以重新生成页面,默认为false。当revalidate为false时,意味着没有重新验证,因此页面将被缓存为已构建,直到下一次构建 notFound 是一个布尔值,允许页面返回404状态,默认为true
export async function getStaticProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }
}
}
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
// 这个函数在构建时在服务器端被调用
// 如果启用重新验证并有新请求进来,它可能会在无服务器函数上再次调用
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js 将尝试重新生成页面:
// - 当请求进来时
// - 最多每 10 秒一次
revalidate: 10, // 秒数
}
}
// 这个函数在构建时在服务器端被调用
// 如果路径尚未生成,它可能会在无服务器函数上再次调用
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
//根据posts获取我们想要预渲染的路径
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// 我们将在构建时仅预渲染这些路径
//{ fallback:blocking } 将服务器渲染页面
// 如果路径不存在,则按需提供
return { paths, fallback: 'blocking' }
}
export default Blog