学习过react的同学都知道redux这个状态管理库,或许同学们都对这个库的API用得溜得起飞,我刚开始学习的时候总觉得redux太难了,相对于vue的vuex来说,redux的学习成本相对较高,vuex已经有自己自带的模板,上手比较容易。但是当你了解过redux后,其实内部的几个常用的API实现起来其实并没有想象中那么难。
createStore
使用redux的基本操作都是创建一个存储状态store变量,它通过readux的createStore方法创建而来,我们尝试实现一个自己的createStore。
新建一个my-redux的文件夹,在文件下新建一个createStore.js的文件,在这里实现核心的createStore方法。
createStore方法接两个参数,reducer是一个纯函数,enhancer加强函数,用来处理中间件。
export default function createStore(reducer, enhancer) {
if (enhancer) {
return enhancer(createStore)(reducer)
}
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)
return () => {
const index = currentListeners.indexOf(listener)
currentListeners.splice(index ,1)
}
}
dispatch({ type: 'REDUX/DREAM' })
return {
getState,
dispatch,
subscribe
}
}
createStore方法最终返回getState,dispatch,subscribe三个方法,getState用来获取store的当前状态,dispatch用来修改状态,subscribe用来处理当数据发生改变,需要做什么。
首先,先判断是否有enhancer方法,有的话先进行对createStore的进一步加强,传入reducer得到最终的结果。createStore方法的reducer是必传项,reducer是一个纯函数。通过action的类型来改变currentState的值,currentListners用于执行相应的队列。subscribe用于发布和取消订阅。在createStore方法里需要初始化自动派发dispatch。
applyMiddleware
redux除了createStore核心的API之外,还提供了applyMiddleware方法。顾名思义,这个方法用于处理中间件,配合createStore一起使用,applyMiddleware可以接收一系列的中间件。新建一个applyMiddleware.js文件来编写核心的applyMiddleware。
在函数执行的时候,要保证函数会按照顺序挨个执行,我们定义一个compose函数来辅助,需要判断空数组的兼容情况。
function compose(...funs) {
if (funs.length === 0) {
return arg => arg
}
if (funs.length === 1) {
return funs[0]
}
return funs.reduce((a, b) => (...args) => a(b(...args)))
}
export default function applyMiddleware(...middlewares) {
return createStore => reducer => {
const store = createStore(reducer)
let dispatch = store.dispatch
const midApi = {
getState: store.getState,
dispatch: action => dispatch(action)
}
const middlewareChain = middlewares.map(middleware => middleware(midApi))
dispatch = compose(...middlewareChain)(store.dispatch)
return {
...store,
dispatch
}
}
}
中间件的加强其主要针对的是dispatch的加强,在redux中,store.dispatch派发的action类型只能是对象,在applyMiddleware中,dispatch的加强通过compose方法来完成。最终将store和dispatch导出,dispatch会覆盖原本store的dispatch。
大体的实现就是这样了的啦,想深入学习的同学去github查看源码。