alphatr / think-react-render

react server side rendering for thinkjs 2.x
14 stars 3 forks source link

如果使用redux,想实现thinkjs在server端render #2

Open winnieBear opened 8 years ago

winnieBear commented 8 years ago

如果使用redux,想实现thinkjs在server端render,实现前后端同构,怎么使用你这个中间件呢,有什么建议?

alphatr commented 8 years ago

@winnieBear

对 Redux 了解的不多,我简单说下我的理解:

一个请求过来后,根据参数从数据库取出初始数据,跟着 reducers 一起初始化一个新的 store 实例,根据 store 和 react 模板做服务端渲染,并且将 store 中获取的 state 返回给客户端;

客户端拿到 state 后,同样创建 store,并渲染;

具体结合我这个组件,可能就需要这样来做:

  1. 取出初始数据,初始化 store
var Base = require('./base.js');
var myApp =  require('./somepath/reducers');

module.exports = think.controller(Base, {
    indexAction: function (self) {
        // 异步从数据库或者其他中取出来数据
        return this.model('data').getInitialState(params).then(function (initialState) {

            // 创建一个新的 store 实例
            var store = createStore(myApp, initialState);

            // 将 store assign 到页面供服务端渲染
            this.assign('store', store);

            // 将初始数据 assign 到页面,供客户端渲染用
            this.assign('initialState', JSON.stringify(store.getState()));
            return self.display();
        });
    }
});
  1. 在模板中这样定义,主要是定义 App 的位置和输出 initialState 到页面
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>React</title>
    <script>window.__INITIAL_STATE__ = {{ initialState }};</script>
</head>
<body>
    <div id="app"><App store={store}/></div>
    <script src="/static/bundle.js"></script>
</body>
</html>

服务端的代码基本就是这些;

  1. 客户端初始化
var React = require('react');
var ReactDOM = require('react-dom');
var Redux = require('redux');

var App = require('./somepath/app');
var myApp =  require('./somepath/reducers');

// 使用服务端输出的初始 state 创建 Redux store
var store = Redux.createStore(myApp, window.__INITIAL_STATE__);

// 客户端重新渲染
var appDom = document.getElementById('app');
ReactDOM.render(<App store={store} />, appDom);

上面就是我的一些想法,欢迎交流~