12.3.2 脱水和注水
您可以在百度里搜索“深入浅出React和Redux 艾草文学(www.321553.xyz)”查找最新章节!
12.3.2 脱水和注水
“那你只能脱水了。”周文王说,一手用兽皮扇着风。
“脱水以后,你不会扔下我吧?”
“当然不会,我保证把你带到朝歌。”
——《三体》
在《三体》的科幻故事中,三体星被三个太阳操控,随时可能陷入酷热的境地,所以三体人进化出一种“脱水”的能力,当炎热缺水时,三体人可以脱水进入休眠状态,脱水之后的体重变轻,可以由其他三体人搬运,当水量充足时,只要重新“注水”,三体人就能够复活过来。
React同构中的“脱水”(Dehydrate)和“注水”(Rehydrate)就和三体人的这种奇异能力相似。
服务器端渲染产出了HTML,但是在交给浏览器的网页中不光要有HTML,还需要有“脱水数据”,也就是在服务器渲染过程中给React组件的输入数据,这样,当浏览器端渲染时,可以直接根据“脱水数据”来渲染React组件,这个过程叫做“注水”。使用脱水数据可以避免没有必要的API服务器请求,更重要的是,保证了两端渲染的结果一致,这样不会产生网页内容的闪动。
脱水数据的传递方式一般是在网页中内嵌一段JavaScript,内容就是把传递给React组件的数据赋值给某个变量,这样浏览器就可以直接通过这个变量获取脱水数据。
使用EJS作为服务器端模板,渲染脱水数据的代码模式基本这样,其中appHTML是React的renderToString返回的HTML字符串,而dehydrateState就是脱水数据的JSON字符串表示形式,赋值给了全局变量DEHYDRATED_STATE,在浏览器端,可以直接读取到这个变量:
- appHtml
既然我们使用Redux来管理应用数据,那么脱水数据的就应该是来自于Redux的Store,借助于react-redux的Provider帮助,可以很容易地让所有React都从一个store获得数据,然后我们在调用服务器端渲染的函数renderToString之后调用store的getState函数,得到的结果就可以作为“脱水数据”:
const appHtml = ReactDOMServer.renderToString(
);
const dehydratedState= store.getState();
就像三体人脱水之后就应该变得很轻一样,脱水数据一定不能太大,因为脱水数据要占用网页的大小,如果脱水数据过大,可能会影响性能,让服务器端渲染失去意义。
由此,我们再次看出让Redux Store上的不要存冗余数据的必要性,只要我们保证Store上状态没有冗余,在产生脱水数据的时候就轻松太多,不然很难分辨哪些数据不必要放在脱水数据中。 深入浅出React和Redux