一、前言
服务端渲染理论知识暂且不论,好处是利于首屏加载,以及SEO,具体详情可以去百度一下,因为在公司做了一个react项目,主要用于一个页面的展示功能,正好也使用一下服务端渲染,学习一下,vue用nuxt.js,react用next.js,琢磨了一段时间,用以记录,废话不多说,开始
二、前期准备
我们可以按照next.js官网一步步创建,这里使用create-next-app脚手架,
1)全局安装脚手架
npm install -g create-next-app
2)创建项目
create-next-app --example basic-css my-app
// 这里的basic-css对应package.json里面的name,my-app对应文件夹项目名称,由你决定
项目生成之后,pages对应路由页面,在项目下创建文件夹components,static,分别对应公共组件目录,静态资源目录,这两个目录只能这样命名
3)运行项目
npm install // 安装依赖
npm run dev // 运行项目
4)配置css
创建可以看到pages下的index.js有
<style jsx>{`
... // css代码
`}</style>
意思就是说js代码中内嵌css 用style jsx区分,这样不好的地方就是,如果页面元素过多,导致页面css也过多,使得整个页面过长,不利用开发,而next不支持直接引入css,所以要安装插件
找到官网,css下有红框框中的,可以选择一项我这里选择第一项,css
npm install --save @zeit/next-css
然后在项目根目录下新建next.config.js文件,在里面写入代码,具体可以看文档
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
})
然后在static目录下新建style.css,在这里写你的样式,然后在index.js引入就可以了
import '../static/style.css'
所以现在的目录结构如下:
三、数据获取
1)安装axios
npm install --save axios
- 数据获取
import '../static/style.css';
import { Component } from 'react';
import axios from 'axios'
export default class extends Component {
constructor(props) {
super(props)
console.log(props)
}
static async getInitialProps({ req }) { // 在里面调用接口,会自动运行这里面代码
const data = await axios.get('xxx') // xxx代表接口地址
return { // 返回值将被放入到上方的props中
list: data
}
}
componentDidMount() { }
render() {}
注意哦,上面的componentDidMount中的this 和getInitialProps里面的this不是同一个哦
如果要在getInitialProps使用this.调用方法要加 static 如下:
import '../static/style.css';
import { Component } from 'react';
import axios from 'axios'
export default class extends Component {
constructor(props) {
super(props)
console.log(props)
this.getData()
}
static async getInitialProps({ req }) { // 在里面调用接口,会自动运行这里面代码
const data = await axios.get('xxx') // xxx代表接口地址
return { // 返回值将被放入到上方的props中
list: data
}
}
static getData() {
}
//getData() { //这样写 不写static的话在getInitialProps是调取不到的 会报错
//而如果不写static则可以在componentDidMount调取
//}
componentDidMount() {
//this.getData() //调取的是上面注释代码getData方法
}
render() {}
3)定时器,如果有定时器的需求的话,那就只能使用componentDidMount了,则如下:
import '../static/style.css';
import { Component } from 'react';
import axios from 'axios'
export default class extends Component {
constructor(props) {
super(props)
console.log(props)
this.getData()
}
state = {
}
componentDidMount() {
// 就不用getInitialProps,而上面的state则对应 react state 可以使用this.setState来赋值
}
render() {}
按照上面,可以推断去,componentDidMount对应的事react方面的,而getInitialProps对应的事服务器端的
,所以两者的this不同,你也可以试一试,分别在componentDidMount与getInitialProps console.log()数据,前者对应的事在浏览器控制台打印,而后者对应的是在服务端控制台打印。所以componentDidMount对应的是react的state,而getInitialProps 对应的是props,你不能把服务端的props赋值给state,会报错,提醒你state不是响应的,所以你只能有一个选择,要么选择react端的state,要么选择服务端的props,看你需求,
因为我是用定时器需求的,所以我选择react端的state。