[Redux/Mobx] 说说Redux的实现流程

通过分析redux的几个核心api,来看如何实现redux

  • store.subscribe: 订阅数据的变化
  • store.dispatch:dispatch后改变state,同时通知store.subscribe函数执行,上面这两个函数可以利用发布-订阅模式
  • store.getState: 通过这个函数直接返回内存中的state变量即可
    简单的实现如下
export function createStore(reducer, enhancer) {

    if (enhancer && typeof enhancer === 'function') {
        const newCreateStore = enhancer(createStore);
        const newStore = newCreateStore(reducer);
        return newStore;
    }

    let state;              // state记录所有状态
    let listeners = [];     // 保存所有注册的回调

    function subscribe(callback) {
        listeners.push(callback);       // subscribe就是将回调保存下来
    }

    // dispatch就是将所有的回调拿出来依次执行就行
    function dispatch(action) {
        state = reducer(state, action);
        for (let i = 0; i < listeners.length; i++) {
            const listener = listeners[i];
            listener();
        }
    }

    // getState直接返回state
    function getState() {
        return state;
    }

    // store包装一下前面的方法直接返回
    const store = {
        subscribe,
        dispatch,
        getState
    }

    return store;
}

export function combineReducers(reducerMap) {
    const reducerKeys = Object.keys(reducerMap);    // 先把参数里面所有的键值拿出来

    // 返回值是一个普通结构的reducer函数
    const reducer = (state = {}, action) => {
        const newState = {};

        for (let i = 0; i < reducerKeys.length; i++) {
            // reducerMap里面每个键的值都是一个reducer,我们把它拿出来运行下就可以得到对应键新的state值
            // 然后将所有reducer返回的state按照参数里面的key组装好
            // 最后再返回组装好的newState就行
            const key = reducerKeys[i];
            const currentReducer = reducerMap[key];
            const prevState = state[key];
            newState[key] = currentReducer(prevState, action);
        }

        return newState;
    };

    return reducer;
}

// 参数支持多个中间件
export function applyMiddleware(...middlewares) {
    function enhancer(createStore) {
      function newCreateStore(reducer) {
        const store = createStore(reducer);
        
        // 多个middleware,先解构出dispatch => newDispatch的结构
        const chain = middlewares.map(middleware => middleware(store));
        const { dispatch } = store;
        
        // 用compose得到一个组合了所有newDispatch的函数
        const newDispatchGen = Redux.compose(...chain);
        // 执行这个函数得到newDispatch
        const newDispatch = newDispatchGen(dispatch);
  
        return {...store, dispatch: newDispatch}
      }
      
      return newCreateStore;
    }
    
    return enhancer;
  }

 

个人简介

我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,
但坚持一定很酷。欢迎大家一起讨论

















主目录

与歌谣一起通关前端面试题