王志远,微医前端技术部
前言
既然是 SSR 框架,核心点之一就是服务端渲染优化SEO,即有些关键数据得先请求后端获取并组装好内容后,再返回给客户端便于搜索引擎抓取。这个请求后端的地方就是 SSR 服务端渲染钩子,在 nuxt 是asyncData,而在 next 中getInitialProps。
使用
注意:getInitialProps 只会在组件是路由组件时生效(即身为页面 pages 目录下的一员),更多注意见下面【注意点模块】
正常情况下使用
在类本身挂载静态函数,这个函数需要是 async 函数,返回的数据将放在 props 上。
// 获取此组件的初始化对象 此函数的返回值将成为此组件的属性对象
UserList.getInitialProps = async (ctx) => {
console.log("2.UseList.getInitialProps ctx", ctx);
let list = [
{ _id: 1, username: "zhangsan", password: "1" },
{ _id: 2, username: "lisi", password: "2" },
];
return { list };
};
自定义_app.tsx时使用
当我们覆盖了_app.tsx时,我们就需要自己去实现调用getInitialProps的逻辑了,需要在_app.tsx中实现获取子组件的getInitialProps,请求后将数据放在 props 上然后在渲染时传递给component组件。
import React from 'react';
import App, { Container } from "next/app";;
import "antd/dist/antd.css";
class LayoutApp extends App<any> {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
// 执行当前页面的getInitialProps
let data = await Component.getInitialProps(ctx);
pageProps = { ...data };
}
return { pageProps };
}
render() {
let { Component } = this.props as any;
return (
<Component {...pageProps}/>
);
}
}
export default LayoutApp;
注意点
getInitialProps只会在组件是路由组件时生效(即身为页面pages目录下的一员)- 在页面级别渲染时只会被执行一次,即服务端渲染或每次切换客户端渲染都会被执行,但服务端渲染时客户端不会执行
- 执行时会先执行
getInitialProps再执行constructor,并且在getInitialProps中 this 不指向实例(因为是静态方法) getInitialProps异步获取数据,页面会等到页面数据都获取加载完成后才进行渲染- 因为是双端执行,所以需要尤为小心地使用仅一端存在的
API,如:document、window等 - 因为是双端执行,数据获取需要某些时候考虑如何取用户状态如服务端侧可以使用
ctx.req/ctx.res - 因为是双端执行,在
getInitialProps方法里进行页面跳转也需要根据端侧不同使用跳转方式也不同