12.3.1 React服务器端渲染HTML
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
12.3.1 React服务器端渲染HTML
React在服务器端渲染使用函数和浏览器端不一样,在浏览器端的函数是render,接受两个参数,第一个是一个React组件,第二个是这个组件需要装载的DOM节点位置,代码模式是这样:
import ReactDOM from 'react-dom';
React.render(
当render函数被调用的时候,必须保证id为root的DOM元素作为容器真的存在,render函数的工作就是启动RootComponent的装载过程,最后产生的DOM元素就存在root容器之中。
在浏览器端,最终的产出是DOM元素,而在服务器端,最终产出的是字符串,因为返回给浏览器的就是HTML字符串,所以服务器端渲染不需要指定容器元素,只有一个返回字符串的函数renderToString,使用这个函数的代码模式是这样:
import ReactDOMServer from 'react-dom/server';
const appHtml = ReactDOMServer.renderToString(
renderToString函数的返回结果就是一个HTML字符串,至于这个字符串如何处理,要由开发者来决定,当然,在这个例子中,为了和浏览器端一致,我们会把返回的字符串嵌在id为root的元素中。
当然,只是把renderToString返回的字符串在浏览器中渲染出来,用户看到的只是纯静态的HTML而已,并不具有任何动态的交互功能。要让渲染的HTML“活”起来,还需要浏览器端执行JavaScript代码。因为React将HTML、样式和JavaScript封装在一个组件中的特点,所以让React组件渲染出的HTML“活”起来的代码就存在于React组件之中,也就是说,如果应用React服务器端渲染,一样要利用React浏览器端渲染。
过程是这样,服务器端渲染产生的React组件HTML被下载到浏览器网页之中,浏览器网页需要使用render函数重新渲染一遍React组件。这个过程看起来会比较浪费,不过在浏览器端的render函数结束之前,用户就已经可以看见服务器端渲染的结果了,所以用户感知的性能提高了。
为了避免不必要的DOM操作,服务器端在渲染React组件时会计算所生成HTML的校验和,并存放在根节点的属性data-react-checksum中。在浏览器渲染过程中,在重新计算出预期的DOM树之后,也会计算一遍校验和,和服务器计算的校验和做一个对比。如果发现二者相同,就没有必要做DOM操作了,如果不同,那就应用浏览器端产生的DOM树,覆盖掉服务器产生的HTML。
很明显,如果服务器端渲染和浏览器端渲染产生的内容不一样,用户会先看到服务器端渲染的内容,随后浏览器端渲染会重新渲染内容,用户就会看到一次闪烁,这样给用户的体验很不好。所以,实现同构很重要的一条,就是一定要保证服务器端和浏览器端渲染的结果要一模一样。
如果我们能保证服务器端和浏览器使用的React组件代码是一致的,那导致渲染结果不一致的唯一可能就是提供给React组件的数据不一致。
为了让两端数据一致,就要涉及“脱水”和“注水”的概念。 深入浅出React和Redux