import React from 'react'
import ReactDOM from 'react-dom'
import { createHashHistory } from 'history'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import { Provider, connect } from 'react-redux'
import createSagaMiddleware from 'redux-saga'
import * as sagaEffects from 'redux-saga/effects'
export default function (opts = {}) {
let history = opts.history || createHashHistory()
let app = {
_models: [],
model,
router,
_router: null,
start
}
function model(m) {
let prefixmodel = prefixResolve(m)
app._models.push(prefixmodel)
}
function router(router) {
app._router = router
}
function start(container) {
let reducer = getReducer(app)
let sagas = getSagas(app)
//let store = createStore(reducer)
let sagaMiddleware = createSagaMiddleware()
app._store = applyMiddleware(sagaMiddleware)(createStore)(reducer)
sagas.forEach(sagaMiddleware.run)
ReactDOM.render(
<Provider store={app._store}>
{app._router('history')}
</Provider>
, document.querySelector(container))
}
return app
}
function getReducer(app) {
let reducers = {}
for (let m of app._models) {//m是每个model的配置
reducers[m.namespace] = function (state = m.state, action) {//组织每个模块的reducer
let everyreducers = m.reducers//reducers的配置对象,里面是函数
let reducer = everyreducers[action.type]//相当于以前写的switch
if (reducer) {
return reducer(state, action)
}
return state
}
}
return combineReducers(reducers)//reducer结构{reducer1:fn,reducer2:fn}
}
function prefix(obj, namespace) {
return Object.keys(obj).reduce((prev, next) => {//prev收集,next是每个函数名
let newkey = namespace + '/' + next
prev[newkey] = obj[next]
return prev
}, {})
}
function prefixResolve(model) {
if (model.reducers) {
model.reducers = prefix(model.reducers, model.namespace)
}
if (model.effects) {
model.effects = prefix(model.effects, model.namespace)
}
return model
}
function getSagas(app) {
let sagas = []
for (let m of app._models) {
sagas.push(function* () {
for (const key in m.effects) {//key就是每个函数名
const watcher = getWatcher(key, m.effects[key])
yield sagaEffects.fork(watcher) //用fork不会阻塞
}
})
}
return sagas
}
function getWatcher(key, effect) {
return function* () {
yield sagaEffects.takeEvery(key, function* (action) {//对action进行监控,调用下面这个saga
yield effect(action, sagaEffects)
})
}
}
// router.js
import * as routerRedux from 'react-router-redux';
export * from 'react-router-dom';
export { routerRedux }