关于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
基本使用完全可以参照官方文档 ,Next的github仓库中有一个example目录,里面有很多 demo ,从开发到项目部署都有。例如引入antd, redux 、 配合express部署等。
在这里只说一些需要注意的点。
路由
Next默认匹配pages目录的index.js作为根路径/,其他的路径也是这样按文件名匹配的。例如我在pages目录新建一个blog.js,那么我访问/blog路由就能看到blog.js对应的页面
引入NProgress进度条
这里需要自定义 ,引入withRouter高阶组件,监听Router的onRouteChangeStart和onRouteChangeComplete事件。
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
进行服务端渲染,一部分原因是有利于SEO。next提供了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>