基于next服务端渲染框架和koa服务端解析框架的react开发小总结

前言:真正意义上的前后端分离,前端ssr服务器渲染页面,加载静态资源,数据还是储存在后台服务器中。

1.packjson配置:

“script”:{
"dev": "node server",
"start": "npm run build && cross-env NODE_ENV=production node server", // start命令即创造生产环境
"export": "next export",
"build": "next build"
}

2.强制把异步操作同步:

(1) async function(){ await axios请求 }

在使用 async/await 的时候,可以使用 Promise.all 来 await 多个 async 函数

await Promise.all([anAsyncCall(), thisIsAlsoAsync(), oneMore()])

(2) co,yield

import co from 'co'
co(function * () { // *代表是异步的
let result = yield Promise.resolve(1)
 console.log(result) // 1
}).catch(function (err) {
console.log(err)
})

3.react生命周期(^15.6.2):

componentWillMount()
在组件挂载之前调用一次。如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次


componentDidMount()
在组件挂载之后调用一次。这个时候,子主键也都挂载好了,可以在这里使用refs(dom)。 // ssr渲染此生命周期被取消掉,直接用:
static getInitialProps = async (props) => {
    const channelRes = await fetcher(', {})
    const channelInfos = channelRes.data
    return {
      channelRes,
      channelInfos,
    }
  }

componentWillUnMount() { clearInterval(this.timer); }
组件被销毁时调用,如果有计时器记得把组件内的计时器clear掉

4.react规范:

map生成的元素需要key值,组件合理闭合,无需包裹其他元素要 />结束

jsx写法:<>内容html渲染,{ }花括号内容js渲染,return()圆括号写内容 (jsx内组件名要大写字母开头!!!)

react性能优化:

尽量减少无意义的render,可用PureComponent(浅比较)或者 react-addons-pure-render-mixin插件,

import React, { Component } from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';
class App extends Component {
constructor(props) {
super(props);
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
}

5.设置默认props(react) :

static getDefaultProps = async ()=> {

await axios 请求

return {your need props}

}

next.js中用getInitialProps获取初始化数据,服务器渲染,componentDidmount周期失效

注:此props只最外层组件可用,子组件请用react生命周期请求接口

6.监视HTTP请求,获得url参数:

运用next.js服务端框架渲染页面,server.js文件里:

 const Koa = require('koa')
 const router = require('koa-router')() //运用koa服务端解析框架搭开发环境
 const next = require('next')
 const dev = process.env.NODE_ENV !== 'production'
 const app = next({ dev })  // dev可决定next库的版本是开发环境还是生产环境
 const MobileDetect = require('mobile-detect') //node里的方法,判断请求源的设备信息

  app.prepare() // next.js方法
  .then(() => {
  const server = new Koa()
  router.get('/somePage/:somePageId', async (ctx) => {
    const actualPage = '/somePage'
    const queryParams = { somePageId: ctx.params.somePageId }
    const md = new MobileDetect(ctx.req.headers['user-agent'])
    if (md.phone()) {
    ctx.redirect('https://baidu.com/play/' + ctx.params.somePageId) //重定向url
    } else {
    await app.render(ctx.req, ctx.res, actualPage, queryParams)//next.js框架方法,用于渲染页面
        }
    server.listen(5677, (err) => {
      if (err) throw err
      console.log('> Ready on http://localhost:5677')
    }) // 启动服务器并监视端口号5677

    server.use(router.routes())
    })

注:koa2的router.get()方法相当于后台拦截器,当监视到url的/somePage/:somePageId请求时就通过第二个参数进行处理,ctx返回页面响应内容

next.js里的render()方法用来手动渲染页面,参数(req, res, '/a', query):ctx.request,ctx.response,页面路径,路径所带参数(传入一个对象)

somePage组件里:

this.props.query.activityId获取到url所带参数

7.标签内直接innerHtml

react:

<div dangerouslySetInnerHTML={{ __html:item.mdata.videos[0].intro.slice(0, 300) + '...' }}></div> 

注:dangerouslySetInnerHTML和_html成套搭配

vue:

<div v-html=""></div>

8.es6语法:

模版字符串:`${props.height}px` === ' '+props.height+'px'

处理数组:map(遍历并返回新数组),fliter(过滤并返回新数组),forEach(遍历改变不返回新数组),reduce(累计并返回结果)

箭头函数 :const a =(a,b)=> a+b === function a(a,b){return a+b}

对变量的声明 const:变量被声明后就不被改变,let:变量上下文块级作用域,声明一次即可

参数赋默认值:var test =(params = {} )=> { console.log(typeof params) } ; test(); //object (赋值为了防止忘了传参数报错)

{ a } === { a : a }

9.开发流程:

开发dev :package.json=>next.config.js=>server.js

生产start : next build => next.config.js=>server.js

10.数据请求:

前端用node服务器做页面渲染,数据储存还是在后台服务器里,

A服务器请求B服务器接口拿到数据,有两种方法:

1.cros后台设返回设置允许浏览器跨域。(跨域是浏览器这边的拦截)

2:Nginx转发

3:node的request模块做代理

下面介绍node怎么做转发:

const Koa = require('koa')
const router = require('koa-router')()
const request = require(‘request’) //做转发
const app = next()
app.prepare()
  .then(() => {
    router.post('/api', function (req, res, next) {
      const objUrl = 'url&sectionid=' + req.body.activityId
      request(objUrl, function (error, response, body) {
        if (!error && response.statusCode === '200') {
          res.send(body)
        }
      })
    })
 })