msforest / notebook

好记性不如烂笔头,记录知识的点点滴滴。
https://github.com/msforest/notebook/wiki
0 stars 0 forks source link

redux 源码解读 #30

Open msforest opened 5 years ago

msforest commented 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;

image