react server rendering(服務端渲染)

weixin_33866037發表於2016-05-25

一個react專案在伺服器端渲染,其實最本質的一個點就在於路由。路由一般採用的是react-router。其實在react-router裡,它本身就提供了伺服器端渲染的方法,下面對它進行一下小小的學習。

服務端渲染跟客戶端渲染有點不同,因為,服務端渲染需要傳送500/30x,還要在渲染前就要請求資料。

react-router提供了兩個更底層的api,一個是match,另一個是RouterContext

match是用來匹配路由的,但是它沒有渲染的功能。
RouterContext用來同步渲染components的。

看個例子:

import { renderToString } from 'react-dom/server'
import { match, RouterContext } from 'react-router'
import routes from './routes'
serve((req, res) => {
    match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { 
        if (error) { 
            res.status(500).send(error.message) 
        } else if (redirectLocation) { 
            res.redirect(302, redirectLocation.pathname + redirectLocation.search) 
        } else if (renderProps) {
            res.status(200).send(renderToString(<RouterContext {...renderProps} />)) 
        } else { 
            res.status(404).send('Not found') 
        } 
    })
})

這是一個非常簡單的在服務端渲染例子,但是現在一個最重要的問題,就是如何傳資料呢?

在react專案中,一般是用redux來進行資料的管理的。redux 裡有個store維護的state狀態樹。那麼在和api進行資料互動的時候,如何將資料放在store裡面呢?

基本的思路就是,在createStore的時候,將與api互動的方法同時傳入進去,這樣,在store中的action可以呼叫那個庫。呼叫庫去請求資料,一般是個promise物件,取到資料之後,然後在reducer中將資料reduce進state樹中。就完成了這個過程。

其實最最本質的,就是讓action能去api請求資料,只要action請求到了資料並且能進入reducer,那就成功了。這個思路跟客戶端渲染也沒有什麼區別。

在服務端渲染還有一個致命的報錯。來自於webpack。

在client,webpack可以require()各種靜態資源,但是在node 環境中,require()是隻能用於javascript 的。

這裡就要靠一個library了。
webpack-isomorphic-tools
具體的介紹在github中都有,也不在這裡贅述。

另外再向大家推薦一個完整的react例子,裡面有很多很多東西可以參考借鑑,甚至可以直接拿過來做自己的專案。
react栗子

相關文章