react-dom 的 renderToString 与 renderToStaticMarkup

官方文档地址

介绍

renderToStringrenderToStaticMarkup 都是同 render 一样都是 react-dom 包提供的方法
不过 renderToStringrenderToStaticMarkupreact-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])

renderToStringrenderToStaticMarkup 只接受一个参数
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, 未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 7,848评论 1 18
  • react+redux+webpack+babel+npm+shell+git这方面的内容我会随时更新,更新内容放...
    liangklfang阅读 3,848评论 0 1
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,905评论 25 709
  • 参考文章:深度剖析:如何实现一个Virtual DOM 算法 作者:戴嘉华React中一个没人能解释清楚的问题——...
    waka阅读 11,210评论 0 21
  • 小老板问我孔雀开屏怎么说。。。呃,不会。。。去查字典呀,可是这个字典上真心没有。也不能说没有啦,有道字典上说是:“...
    海归程序猿奶爸阅读 9,417评论 0 4

友情链接更多精彩内容