1 | import React from 'react'
|
2 | import { hydrate } from 'react-dom'
|
3 | import { browserHistory, match, Router } from 'react-router'
|
4 | import { syncHistoryWithStore } from 'react-router-redux'
|
5 | import { Provider } from 'react-redux'
|
6 | import { createStore, applyMiddleware, compose } from 'redux'
|
7 |
|
8 |
|
9 |
|
10 | import ReduxMiddleware from './ReduxMiddleware'
|
11 | import ReduxReducer from './ReduxReducer'
|
12 | import ReactRouter from './ReactRouter'
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | const DEFAULT_ROOT_DOM_ID = 'root'
|
20 |
|
21 |
|
22 | export let store
|
23 |
|
24 | export default class ReactApp {
|
25 |
|
26 | constructor(opt) {
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | this.rootDom = (opt && opt.rootDom) ? opt.rootDom : DEFAULT_ROOT_DOM_ID
|
33 |
|
34 |
|
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 |
|
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 |
|
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 |
|
103 | this.createConfigureStoreFactory()
|
104 | store = this.configureStore(window.__REDUX_STATE__)
|
105 |
|
106 |
|
107 | browserHistory.listen(location => {
|
108 |
|
109 | |
110 |
|
111 |
|
112 | if (typeof options.browserHistoryOnUpdate === 'function')
|
113 | options.browserHistoryOnUpdate(location, store)
|
114 | })
|
115 |
|
116 |
|
117 |
|
118 | const routes = this.react.router.get()
|
119 |
|
120 |
|
121 | const history = syncHistoryWithStore(browserHistory, store)
|
122 |
|
123 |
|
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 | }
|