react服务器渲染及路由同步

首先说明我最后还是没有使用react服务器渲染,一方面是因为我突然发现我不怎么需要服务器渲染,另一方面遇到的坑太多了,而且大多解决方法都是不断的重新安装依赖包,心太累了。

背景

目前我正在做的东西,后台已经用koa搭建好了,可是前端我想折腾一下就作死的用react,已经ant-design尝试了一下,单做前台页面还是ok的,但是一旦和后台一起就有很多问题。

  1. 路由同步怎么解决;
  2. 服务器渲染怎么解决;
  3. reflux状态管理怎么实现;

本文只讲一下第一个和第二个问题,对于服务器渲染其实还有很多讲究,哪些内容需要服务器渲染,哪些不需要(首屏服务器渲染,次屏客户端渲染),怎么实现,这些问题研究下去实在太深了,我要消化消化,此外本文主要讲解实现上的东西,原理我好多也没弄明白。

路由同步+服务器渲染

引入node中加载react的依赖
package.json

1
2
3
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"babel-register": "^6.3.13",

server.js中加载es6和react的相关依赖

1
2
3
4
5
6
7
8
9
10
require('babel-register')({
presets: ['es2015', 'react']
});
//---------react服务器渲染及路由匹配----------
var React = require('react');
var ReactDOM = require('react-dom/server');
var ReactRouter = require('react-router');
var reactR = require('./app/routes');
var swig = require('swig');
//-----------------------------------------

编写koa中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
app.use(function*(next) {
var self = this;
debug('self.path is %s', self.path);
ReactRouter.match({
routes: reactR.default,
location: self.path
}, function(err, redirectLocation, renderProps) {
debug('redirectLocation is %s', redirectLocation);
debug('err is %s', err);
if (err) {
self.status = 500;
} else if (redirectLocation) {
self.redirect(redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
var html = ReactDOM.renderToString(React.createElement(ReactRouter.RouterContext, renderProps));
debug('html page is %s', html);
var page = swig.renderFile('views/index.html', {
html: html
});
self.body = swig.renderFile('views/index.html');
} else {
self.status = 404;
}
});
yield next;
});