介绍
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, 未完待续...