基础渲染方式
当未添加NextJs特殊钩子时,默认为React代码,这时也会对页面进行服务端渲染,返回HTML中会包含页面初始化的内容。例如页面在加载数据前会显示Loading样式,在加载数据后会显示数据列表,那么NextJS返回的HTML中就包含了初始化状态下初次渲染的Loading样式和DOM元素。
预渲染(SSG) —— getStaticProps
export async function getStaticProps({ params }) {
const res = await fetch(
`test/${params.id}`
);
const data = await res.json();
return {
props: {
data,
},
};
}
注意在此函数内部不要写React代码,因为此函数不在React内部。它会在项目打包构建时运行,并把prop传递给React组件(就好像给你的React组件包了一层有数据的高阶组件),然后把拼装数据后的页面作为打包结果输出为完整HTML。当我们访问此页面时,会获取到此完整HTML,达到服务端预渲染的效果。
此函数也可以在服务端触发,当我们设置revalidate为10时,意味着这个页面10s后会过期,我们需要重新生成静态HTML。所以我们会重复地在服务端执行此函数,并返回新的HTML。
SSG适用于页面数据稳定,不会频繁变化的页面,即使我们可以通过revalidate来重新生成HTML,也不能确保数据的实时准确性。
getStaticPaths
export async function getStaticPaths() {
const res = await getData()
const ids = res.product.map(item => item.id)
const pathsWithParams = ids.map(id => ({
params: {
pid: id
}
}))
return {
paths: pathsWithParams,
fallback: true
};
}
如果说预渲染的页面是根据路径url渲染的动态页面,单纯使用getStaticProps会因为不知道生成多少个HTML而报错。getStaticPaths则提供要预渲染的页面的url路径参数,明确了预渲染的动态页面个数。
预渲染(SSR) —— getServerSideProps
与 getStaticProps 只在构建过程中生成一次静态页面,或者定期重新生成页面不同,使用 getServerSideProps,页面在每接收到一条传入请求就重新生成一遍,并且getServerSideProps只会在服务端运行。
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return {
props: {
data
}
};
}
与上文中 getStaticProps 类似,在页面内会传入data数据提供给页面渲染。
getServerSideProps 返回值除了可以设置 props 外还可以使用 notFound 来强制页面跳转到 404。
export async function getServerSideProps(context) {
const data = await getData();
if (!data) {
return {
notFound: true
};
}
return {
props: { data }
}
或者是使用 redirect 来将页面重定向。
export async function getServerSideProps(context) {
const data = await getData();
if (!data) {
return {
redirect: {
destination: '/',
permanent: false
}
};
}
return {
props: { data }
};
}