Open msforest opened 5 years ago
// store.js const initialState = {}; const middlewares = [thunk, logger]; export default createStore(reducers, initialState, compose(applyMiddleware(...middlewares))); // 若有中间件,则返回一个包含全局store和dispatch属性的object,此dispatch!==store.dispatch // 否则,只返回全局的store // App.js ReactDOM.render( <Provider store={store}> <Routes/> </Provider>, document.getElementById('root') ); // 以下为结合以上例子,redux和中间价分析 import {createStore, applyMiddleware, compose, combineReducers} from 'redux' // M1 public function combineReducers(reducers: object) // => 1. 先检查所有reducer是否都真实存在 // 2. 返回一个闭包函数`(state,action)=>{}`作为createStore的第一个参数, 此函数作用是依次执行所有有效的reducer,返回一个新的state,即store.getState的值;若所有reducers返回的action是默认值,则返回上一个state。 // M2 pulic function compose(a: function, b: function, c: function, ...) // => 返回一个闭包函数作为createStore的第三个参数,此函数等于`(...args) => a(b(c(...args)))` // M3 public function applyMiddleware(...middleware) // => 返回一个闭包函数作为compose的返回值,也就是createStore的第三个参数,此函数等于`(createStore) => (reducer, preloadState) => ...middleware() `,依次执行中间件,返回一个新的dispatch, // || 也可直接作为createStore的第三个参数,返回包含state和新的dispatch属性 // M4 public object createStore(reducer: function, preloadState: object, enhance: function) // => store { // dispatch: 接受一个action参数,用于执行M1中所有的reducers,若上一次action的reducers还在执行中,下一次action紧跟着执行会报错,不允许同时执行两次action去修改state,所以reducers要尽可能的简单,不要执行过于复杂、耗时的代码;reducers执行完毕后,立即执行substribe注册的监听器;最后返回相同的action,用于下一个中间件处理当前action,**此action对象要有一个type属性** // getState: 返回当时的state // subscribe: 注册监听器 // replaceReducers: 顾名思义,替代已传入的reducer //} // M5 public function|object bindActionCreators(actionCreators: function|object, dispatch) // => 若返回一个闭包函数,() => dispatch(actionCreator.apply(this, arguments)) // 若返回一个对象,方法全是上面的闭包函数 import thunk from 'redux-thunk' // M6 function createThunkMiddleware(extraArgument) { // {dispatch, getState} 来自于applyMiddleware对每个中间件的遍历传递 // next来自于store.dispatch return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { // 调用action参数的dispatch, 是由applyMiddleware生成的,不等于next return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;