UNPKG

4.13 kBJavaScriptView Raw
1import React from 'react'
2import { hydrate } from 'react-dom'
3import { browserHistory, match, Router } from 'react-router'
4import { syncHistoryWithStore } from 'react-router-redux'
5import { Provider } from 'react-redux'
6import { createStore, applyMiddleware, compose } from 'redux'
7
8//
9
10import ReduxMiddleware from './ReduxMiddleware'
11import ReduxReducer from './ReduxReducer'
12import ReactRouter from './ReactRouter'
13
14//
15
16// import ACTION_TYPE from './ActionType'
17
18// 默认根 DOM 结点 ID
19const DEFAULT_ROOT_DOM_ID = 'root'
20
21// redux store
22export let store
23
24export default class ReactApp {
25
26 constructor(opt) {
27
28 // 实例化1个 Koa 对象
29
30 // this.app = ((Koa) => new Koa())(require('koa'))
31
32 this.rootDom = (opt && opt.rootDom) ? opt.rootDom : DEFAULT_ROOT_DOM_ID
33
34 // redux
35
36 const reduxMiddleware = new ReduxMiddleware()
37 const reduxReducer = new ReduxReducer()
38
39 this.redux = {
40 middleware: reduxMiddleware,
41 reducer: reduxReducer
42 }
43
44
45 // react
46
47 let reactRouter = new ReactRouter()
48 this.__reactRouterExt = {} // 用于扩展客户端路由属性
49
50 this.react = {
51 router: {
52 use: (router) => reactRouter.add(router),
53 get: () => reactRouter.get(),
54 ext: (ext) => Object.assign(this.__reactRouterExt, ext) // 扩展客户端路由
55 }
56 }
57
58 }
59
60 createConfigureStoreFactory() {
61 const reducers = this.redux.reducer.get()
62 const middlewares = this.redux.middleware.get()
63
64 this.configureStore = this.factoryConfigureStore(reducers, middlewares)
65 return this.configureStore
66 }
67
68 factoryConfigureStore(reducers, middlewares) {
69
70 // redux调试
71
72 let devToolsExtension = (f) => f
73 if (__CLIENT__ && __DEV__) {
74 if (window.devToolsExtension) {
75 devToolsExtension = window.devToolsExtension()
76 }
77 }
78
79 //
80
81 return (initialState) => {
82 let store
83 if (__DEV__) {
84 store = createStore(reducers, initialState, compose(
85 applyMiddleware(...middlewares),
86 devToolsExtension
87 ))
88 } else {
89 store = createStore(reducers, initialState, compose(
90 applyMiddleware(...middlewares)
91 ))
92 }
93 return store
94 }
95 }
96
97
98 run(settings = {}) {
99
100 let options = Object.assign({}, settings)
101
102 // __REDUX_STATE__ 是与服务端约定好的存储redux数据对象 (在浏览器端的 html 里存在)
103 this.createConfigureStoreFactory()
104 store = this.configureStore(window.__REDUX_STATE__)
105
106 // react-router
107 browserHistory.listen(location => {
108 // TODO:
109 /*store.dispatch(realtimeLocationUpdate(location))
110 if (typeof options.browserHistoryOnUpdate === 'function')
111 options.browserHistoryOnUpdate(location)*/
112 if (typeof options.browserHistoryOnUpdate === 'function')
113 options.browserHistoryOnUpdate(location, store)
114 })
115
116 //
117
118 const routes = this.react.router.get()
119
120 // 用 react-router-redux 增强 history
121 const history = syncHistoryWithStore(browserHistory, store)
122
123 // 扩展 router 属性
124 let ext = this.__reactRouterExt
125
126 let root = this.rootDom
127
128 match({ history, routes }, (err, redirectLocation, renderProps) => {
129 if (err) {
130 console.log(err.stack)
131 }
132 hydrate(
133 <Provider store={store} >
134 <Router history={history} {...ext} >
135 {routes}
136 </Router>
137 </Provider>,
138 document.getElementById(root)
139 )
140 })
141
142 return {
143 store
144 }
145 }
146
147}