redux源码解析

202 阅读1分钟

redux概述

redux是一个数据管理库 主要有以下几个重要的api

  • getState 获取数据的状态
  • dispatch 派发事件来改变状态
  • subscribe 订阅,当状态发生改变的时候 响应视图的变化

reducer 制定规则 一切按照规则来改变状态 是一个纯函数

下面来手写redux代码

redux 主要是通过createStore来创建一个 store

function createStore(){
    let currentState;
    let currentListeners = [];
    
    function getState(){
        return currentState
    }
    
    function dispatch(action){
        currentState = reducer(currentState,action)
        currentListeners.forEach( listener =>  listener())
    }
    
    function subscribe(listener){
        currentListeners.push(listener)
    }
    
    dispatch({ type: "initial" })
    
    return {
        getState,
        dispatch,
        subscribe
    }
}

最后返回 几个方法

redux中使用中间件

createStore(countReducer,applyMiddleware(logger,thunk))

可以看出 applyMiddleware 来处理redux中间件 下面我们写一下这个函数

function applyMiddleware(...middlewares){
    return function(createStore){
        return function(reducer){
            const store = createStore(reducer)
            let dispatch = store.dispatch;
            let midApi = {
                getState: store.getState,
                dispatch: (action,...args) => dispatch(action,...args)
            }
            let middlewareChain = middlewares.map( middleware => middleware(midApi) )
            dispatch = compose(...middlewareChain)(store.dispatch)//必须要执行一下 
            //最后增强的dispatch 大概长这样
            
            return {
                ...store,
                dispatch
            }

        }
    }
}

//函数式编程基本运算之一 : 合成
function compose(...funcs) {
    if (funcs.length === 0) {
      return args => args;
    }
    if (funcs.length === 1) {
      return funcs[0];
    }
    return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
合成执行的结果 大概张这样  logger(thunk(dispath))

增强之后的dispatch

在页面中dispatch的时候 执行 logger(thunk(dispatch))

看看中间件怎么写

thunk

function thunk({getState,dispatch}){
    return next => action => {
        console.log("*******执行thunk方法**********")
        if(typeof action === 'function'){
            return action(dispatch,getState)
        }
        return next(action)
    }
}

logger

function logger({getState}){
    return next => action => {
        console.log("*******执行logger方法**********")
        console.log("prevState",getState())
        let resultReturn = next(action)
        console.log("prevState",getState())
        return resultReturn
    }
}

可以看出在执行 logger(chunk(dispatch))的时候 logger先执行自己的方法 碰到 next() 方法的时候 这个next 就是下面这个方法

action => {
    console.log("*******执行thunk方法**********")
    if(typeof action === 'function'){
        return action(dispatch,getState)
    }
    return next(action)
}

再继续去执行thunk中间件 最后把所有的中间件都执行完成