Next服务端渲染指北

260 阅读2分钟

关于Next

Next.js 是一个轻量级的 React 服务端渲染应用框架。

那么何为服务端渲染(server side render, SSR)呢?

首先,回顾一下演变过程:

纯后端渲染 -> 单页面应用(前端渲染和交互) -> 同构(后端渲染和前端交互)

  • 服务端渲染:渲染过程在服务器端完成,最终的渲染结果 HTML 页面通过 HTTP 协议发送给客户端。
  • 客户端渲染:服务器端把模板和数据发送给客户端,渲染过程在客户端完成。
  • 同构:浏览器一侧的JS、HTML和服务器一侧使用的JS、HTML使用同样的开发结构,同样的开发思路,同样的开发模式,尽可能实现代码复用

个人认为,确切的说Next做的是同构渲染。使用node做中间层,我们访问时,Next使用服务端渲染,返回已经渲染完成的页面,而在进行交互时,则使用客户端渲染。

Next的使用

安装

npm install --save next react react-dom

基本使用完全可以参照官方文档Nextgithub仓库中有一个example目录,里面有很多 demo ,从开发到项目部署都有。例如引入antd, redux 、 配合express部署等。


在这里只说一些需要注意的点。

路由

Next默认匹配pages目录的index.js作为根路径/,其他的路径也是这样按文件名匹配的。例如我在pages目录新建一个blog.js,那么我访问/blog路由就能看到blog.js对应的页面

引入NProgress进度条

这里需要自定义 ,引入withRouter高阶组件,监听RouteronRouteChangeStartonRouteChangeComplete事件。

import React from 'react'
import App, { Container } from 'next/app'
import {withRouter} from 'next/router'
import Router from 'next/router'
import NProgress from 'nprogress'
import Head from 'next/head';


class MyApp extends App {
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    Router.onRouteChangeStart = (url) => {
      NProgress.start()
      console.log('Router.onRouteChangeStart')
    }
    Router.onRouteChangeComplete = () => {
      console.log('Router.onRouteChangeComplete')
      NProgress.done()
    }
    Router.onRouteChangeError = () => {
      console.log('Router.onRouteChangeError')
      NProgress.done()
    }

    const { Component, pageProps } = this.props;

    return (
      <Container>
        <Head>
          <link rel='stylesheet' type='text/css' href='/static/nprogress.css' />
        </Head>
        <Component {...pageProps} />
      </Container>
    );
  }
}

export default withRouter(MyApp);

获取数据时需要注意的

在获取需要服务端渲染的数据时,记得用官方提供的getInitialProps,这会在你想加载的数据加载完之后再返回给客户端页面。如果将获取数据方法写在componentDidMount之类的react生命周期中,那就会传统react应用一样客户端渲染数据。

自定义head

进行服务端渲染,一部分原因是有利于SEOnext提供了Head组件,可以自定义head标签

import Head from 'next/head'

export default () =>
  <div>
    <Head>
      <title>next服务端渲染指北</title>
      <meta name='keywords' content='nextjs,ssr,服务端渲染'>
      <meta name='description' content='介绍next服务端渲染的使用及使用时值得注意的地方'>
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
    </Head>
    <p></p>
  </div>