React-react16和webpack4来写一个SSR应用

本文的demo仓库在 https://github.com/qiqingjin/blog/tree/master/React_Redux/,喜欢请star哟~

前面的话

React 16开始重视服务器端渲染,也就是SSR,不再严格对比checksum,不知道你的应用升级了么。
Webpack 4的支持主要看依赖的plugin和loader,目前主流plugin已经支持,可以升级咯。

demo地址:https://github.com/qiqingjin/blog/tree/master/React_Redux/demos,使用了React,Redux和Webpack,服务器是Koa,你可以clone这个仓库,使用 https://github.com/qiqingjin/blog/blob/master/React_Redux/README.md 这个步骤进行本地启动。

基本思想

简单来说,我要做的事情就是,写一套react页面,服务器端和浏览器端都可以把它们转换成html页面。当用户请求某些页面时,例如:首页,先进行服务器端渲染,然后返回html页面。浏览器会把服务器端html与浏览器端渲染的html页面对比,并尽量复用服务器端返回的html,展示到浏览器上。注意,React 16不再使用checksum进行严格校验。

面临的问题

  1. 服务器端渲染不会执行ajax请求,如何进行数据请求
  2. 不同的路由,在浏览器端会请求不同的数据,如何在服务器端根据路由来进行数据处理

数据请求

react-dom/server提供了一个renderToString方法,可以把react的虚拟dom,也就是react component的类,转换成html。我们只要在调用这个方法之前,提前执行需要在浏览器端执行的请求就好,看代码:

// demos/server/server.js
const {data: todosData} = await axios.get('http://localhost:667/rest/todos');

然后需要获取react组件,我这里使用koa,node端不支持import等方法,需要用webpack把react组件编译,注意,服务器端编译的config配置和浏览器端编译的config略有不同,请看demos/client/webpack.config.jsdemos/client/webpack.config.ssr.js。获取react组件的代码:

// demos/server/server.js
const indexBundle = require('./dist/main.ssr');
const indexApp = indexBundle.__esModule ? indexBundle.default : indexBundle;

获取react组件后,需要把数据注入到redux的createStore方法中,再传给react组件,保证react组件中的storedispatch等方法。

// demos/server/server.js
const store = indexApp.createStore(initData);
const instance = indexApp.createApp(store);
const todosStr = ReactDOMServer.renderToString(instance);

最后,需要把数据放到window对象上,让浏览器端用来渲染浏览器端html,然后与服务器端html对比,尽量复用。

// demos/server/server.js
const syncScript = `
                    
                    

你可能感兴趣的:(Redux,React)