只需cv,实战中学习next | 服务端渲染钩子getInitialProps

463 阅读2分钟

王志远,微医前端技术部

前言

既然是 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,如:documentwindow
  • 因为是双端执行,数据获取需要某些时候考虑如何取用户状态如服务端侧可以使用 ctx.req/ctx.res
  • 因为是双端执行,在 getInitialProps 方法里进行页面跳转也需要根据端侧不同使用跳转方式也不同