基於next服務端渲染框架和koa服務端解析框架的react開發小總結

前言:真正意義上的先後端分離,前端ssr服務器渲染頁面,加載靜態資源,數據仍是儲存在後臺服務器中。html

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.強制把異步操做同步vue

(1) async function(){ await axios請求 }node

在使用 async/await 的時候,可使用 Promise.all 來 await 多個 async 函數react

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

(2) co,yieldes6

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:npm


在組件掛載以前調用一次。若是在這個函數裏面調用setState,本次的render函數能夠看到更新後的state,而且只渲染一次

componentWillMount()

在組件掛載以後調用一次。這個時候,子主鍵也都掛載好了,能夠在這裏使用refs(dom)。 // ssr渲染今生命週期被取消掉,直接用:componentDidMount()
static getInitialProps = async (props) => {
    const channelRes = await fetcher(', {})
    const channelInfos = channelRes.data
    return {
      channelRes,
      channelInfos,
    }
  }

componentWillUnMount() { clearInterval(this.timer); }
組件被銷燬時調用,若是有計時器記得把組件內的計時器clear掉

4.react規範:json

map生成的元素須要key值,組件合理閉合,無需包裹其餘元素要 />結束axios

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)
        }
      })
    })
 })
相關文章
相關標籤/搜索