介紹
renderToString
與 renderToStaticMarkup
都是同 render
一樣都是 react-dom
包提供的方法
不過 renderToString
和 renderToStaticMarkup
在 react-dom/server
內
import {render} from 'react-dom'
import {renderToString} from 'react-dom/server'
import {renderToStaticMarkup} from 'react-dom/server'
render
方法不用多說, 是用于瀏覽器端渲染, 學習過 react
的都接觸過
render
方法接受 2 個參數 render([react element], [DOM node])
而 renderToString
與 renderToStaticMarkup
只接受一個參數
renderToString(react element)
renderToStaticMarkup(react element)
但都返回一段HTML
字符串, 這就使得 react
在服務端渲染成為可能.
演示代碼
如代碼所示
-
服務端
使用renderToString/renderToStaticMarkup
方法將<Hello />
組件渲染到#react-target
節點內
import {renderToString} from 'react-dom/server'
import React from 'react'
import KoaRouter from 'koa-router'
import Hello from '../../react/server'
app.get('/hello', (ctx, next) => {
ctx.body = `
<html>
<head>
<title>title</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<div id="react-target">${renderToString(<Hello />)}</div>
{/* <div id="react-target">${renderToStaticMarkup(<Hello />)}</div> */}
<script src="/main.js"></script>
</body>
</html>
`
})
-
瀏覽器端
使用render
方法將<Hello />
組件渲染到#react-target
節點內
render(<Hello />, document.getElementById('react-target'))
區別
-
renderToString
方法渲染的時候帶有data-reactid
屬性. -
renderToStaticMarkup
則沒有data-reactid
屬性, 可以節省一點流量.
data-reactid
簡單的說就是 react 組件
的一個唯一標示 id, 具體可以去 google 下
對于服務端渲染而言
使用
renderToStaticMarkup
渲染出的是不帶data-reactid
的純html
在前端react.js
加載完成后, 之前服務端渲染的頁面會抹掉之前服務端的重新渲染(可能頁面會閃一下). 換句話說 前端react
就根本就不認識之前服務端渲染的內容,render
方法會使用innerHTML
的方法重寫#react-target
里的內容而使用
renderToString
方法渲染的節點會帶有data-reactid
屬性, 在前端react.js
加載完成后, 前端react.js
會認識之前服務端渲染的內容, 不會重新渲染DOM 節點
, 前端react.js
會接管頁面, 執行componentDidMout
綁定瀏覽器事件
等 這些在服務端沒完成也不可能執行任務.
tips
- 服務端渲染的時候不要習慣性地寫成下面這種形式
<div id="react-target"> ${renderToString(<Hello />)} </div>
而應該寫成沒有空格的形式, 如下
<div id="react-target">${renderToString(<Hello />)}</div>
因為這樣會增加空格, 導致前端 react.js
不認識之前服務端渲染的內容, 導致重新渲染!
- 另外一點需要注意的是前后端渲染的內容應該保持一致
- DOM 結構
- store
這里還沒有涉及到 stote, 未完待續...