Next.js如何为我们预渲染页面
getStaticProps
通过在页面(pages)中添加导出的getStaticProps函数,我们可以告诉Next.js我们想要预渲染的页面。Next.js将在构建时(yarn build)
运行此函数,并将返回的数据序列化为JSON,以便在页面加载时可以使用。
此函数的返回值是固定的,必须是一个对象
export const getStaticProps: GetStaticProps = async () => {
const post = (await fetch(`https://api/todos`)).json();
return {
props: {
post,
},
};
}
props
返回对象中包含props键,其值是要传递给页面的数据。页面可以通过添加props参数获取此数据。
const HomePage = (props: { post: object }) => {
const { post } = props;
return (
<div>
<h1>{ post.title }</h1>
<p>{ post.body }</p>
</div>
);
}
revalidate
通过在返回值中添加revalidate: x
(x是数字类型), 告诉Next.js,这个页面应该在被构建和部署之后,
每过x秒重新执行getStaticProps函数并生成页面
export const getStaticProps: GetStaticProps = async () => {
const post = (await fetch(`https://api/todos`)).json();
return {
props: {
post,
},
revalidate: 10,
};
}
notFound
通过在返回值中添加notFound: true
, 告诉Next.js,如果没有数据,就返回404页面。
getStaticPaths
对于动态路由来说, 开发者必须让Next.js知道哪些路径是预渲染的。这是通过在页面中添加导出的getStaticPaths函数来完成的。
它的返回值是固定的,必须是一个对象, 包含paths键,其值是一个数组,数组中包含了预渲染的路径参数。
Next.js将在构建时运行getStaticPaths函数,并将返回的路径参数数组在getStaticProps函数中使用, 对于每一个页面创建它的实例。
例如,如果您的页面路径是pages/posts/[id].tsx
,则可以通过以下方式导出getStaticPaths函数:
export const getStaticPaths: GetStaticPaths = async () => {
const paths = [
{ params: { id: '1' } },
{ params: { id: '2' } },
{ params: { id: '3' } },
];
return {
paths,
fallback: false,
};
}
同时, 你还需要在pages/posts/[id].tsx
中添加getStaticProps
函数, 获取getStaticPaths函数返回的路径参数id数组。
export const getStaticProps: GetStaticProps = async (context) => {
const { id } = context.params;
const post = (await fetch(`https://api/todos/${ id }`)).json();
return {
props: {
post,
},
};
}
这个例子的结果是,Next.js会在构建时为每个id值生成一个页面实例, 如果getStaticProps中添加了revalidate,
那么Next.js会在x秒后重新运行getStaticPaths和getStaticProps函数,并生成每个页面实例。
fallback
getStaticPaths的返回值中的fallback属性是一个布尔值。
true
fallback: true
表示,如果没有当前路由的页面实例,不会返回404页面,但是会在后台运行getStaticProps函数,直到有页面生成。
-
由getStaticPaths返回的路径参数数组会由getStaticProps在构建时生成每个页面实例。
-
用户在访问那些没有在构建时被预渲染的页面实例时,不会收到404页面。服务器会先返回一个“fallback
”版本(页面组件的props为空, router.isFallback = true)的页面. -
在后台,Next.js 会静态生成请求的路径 HTML 和 JSON。这包括运行 getStaticProps。
-
完成后,浏览器会收到已被生成的路径的 JSON。这将用于自动呈现具有所需props的页面。从用户的角度来看,页面将从"fallback"
页面切换到完整页面。 -
同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像在构建时预呈现的其他页面一样。
如果您的应用程序有大量依赖于数据的静态页面(例如非常大的电子商务网站),则该选项很有用。如果你想预渲染所有产品页面,构建将花费很长时间。
相反,您可以静态生成一小部分页面并使用 fallback: true 来处理其余页面。当有人请求尚未生成的页面时,用户将看到带有加载指示器或骨架组件的页面。
不久之后,getStaticProps 完成,页面将使用请求的数据呈现。从现在开始,每个请求同一页面的人都将获得静态预渲染页面。
这可确保用户始终拥有快速体验,同时保留快速构建和静态生成的优势。
fallback: true 不会更新生成的页面. 如果你想要更新页面, 你需要重新构建.
相关概念查看Incremental Static Regeneration(ISR)
false
fallback: false
表示,如果没有当前路由的页面实例,就返回404页面,不会在后台运行getStaticProps函数。
所以, fallback: false 比较适合用于较小的静态网站,只有等网站的管理者添加内容时,重新让Next.js构建后,才会生成新的页面。
blocking
如果fallback: blocking
,则 getStaticPaths 未返回的新路径将等待生成 HTML,与 SSR 相同(因此阻塞),然后缓存以供将来请求使用,因此每个路径的页面只生成一次。
- 构建时未生成的路径不会产生 404 页面。相反,Next.js 将在第一次请求时进行 SSR 并返回生成的 HTML。
- 完成后,浏览器会收到生成路径的 HTML。从用户的角度来看,它将从“浏览器正在请求页面”过渡到“完整页面已加载”。没有加载/回退状态的闪烁。
- 同时,Next.js 将此路径添加到预渲染页面列表中。对同一路径的后续请求将提供生成的页面,就像在构建时预呈现的其他页面一样。
- 默认情况下,‘blocking’ 不会更新生成的页面。如果您希望更新页面,则需要重新构建。
getServersideProps
如果您从页面导出一个名为 getServerSideProps(服务器端渲染)的函数,Next.js 将使用 getServerSideProps 返回的数据在每个请求上预渲染该页面。
getServerSideProps 仅在服务器端运行,从不在浏览器上运行。如果页面使用 getServerSideProps
- 当您直接请求此页面时,getServerSideProps 在请求时运行,此页面将使用返回的 props 进行预渲染
- 当您通过 next/link 或 next/router 在客户端页面转换上请求此页面时,Next.js 会向服务器发送 API 请求,服务器运行
getServerSideProps - 当从页面导出一个名为 getServerSideProps(服务器端渲染)的函数时,Next.js 将使用 getServerSideProps
返回的数据在每个请求上预渲染该页面。如果您想要获取经常更改的数据并让页面更新以显示最新数据,这将很有用。 - 您可以在顶级范围内导入模块以在 getServerSideProps 中使用。使用的导入不会为客户端捆绑。这意味着您可以直接在
getServerSideProps 中编写服务器端代码,包括从数据库中获取数据。
export const getServerSideProps: GetServerSideProps = async (context) => {
/*
* params: 参数
* req: http请求
* res: http响应
* */
const { params, req, res } = context;
return {
props: {}, // will be passed to the page component as props
}
}