function dispatch(action) {
if (!isPlainObject(action)) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
if (typeof action.type === 'undefined') {
throw new Error(
'Actions may not have an undefined "type" property. ' +
'Have you misspelled a constant?'
)
}
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.')
}
try {
isDispatching = true
currentState = currentReducer(currentState, action)
} finally {
isDispatching = false
}
var listeners = currentListeners = nextListeners
for (var i = 0; i < listeners.length; i++) {
listeners[i]()
}
return action
}
function subscribe(listener) {
if (typeof listener !== 'function') {
throw new Error('Expected listener to be a function.')
}
var isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
return function unsubscribe() {
if (!isSubscribed) {
return
}
isSubscribed = false
ensureCanMutateNextListeners()
var index = nextListeners.indexOf(listener)
nextListeners.splice(index, 1)
}
}
redux源码分析(一)
现如今前端应用已经是数据驱动试图的时代,但当应用越来越大,越来越复杂时,其数据状态的管理就变得至关重要,基于facebook的flux状态管理框架,redux也应运而生了,其核心思想就是如下几点
1、应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。
2、惟一改变 state 的办法是触发 action,一个描述发生什么的对象。
3、为了描述 action 如何改变 state 树,你需要编写 reducers。
针对这几条核心思想,来统一管理一个store,redux的源码实现也非常的简介清晰,下面将结合自己的阅读对其源码进行一定的分析。先来看看整个src目录
所有代码加起来粗略估算还不超过700行,可以看出redux的实现非常简介,其思想有很多值得我们借鉴的地方。
首先来看最核心的createStore.js文件,它直接对外抛出了一个创建store的createStore函数供外部调用,其接收一个纯函数reducer,一个初始的state,以及一个可选的增强函数enhancer
此篇先来看看没有enhancer的情况(enhancer的情况将放在后面介绍),按照redux的核心,要改变state,必须dispatch一个action,那就先来看看dispatch函数的源码
刚开始对传入的action进行了校验,action必须是一个对象,且按约定,应该包含一个type属性。然后
currentState = currentReducer(currentState, action)
就是纯函数reducer的执行,其接收一个当前的state和这个action,根据action的type来进行分发,返回一个新的state,如果未匹配到,就返回初始的state。一个基本的reducer应该是这样接着可以看到会遍历当前的listener并执行,这些listener是在subscribe订阅函数中注册的,每当dispatch一个action都会执行这些listener,源码如下,其将返回一个取消订阅的函数,可以随时取消订阅。
整个store暴露出了几个接口,以供调用
下篇将介绍bindActionCreators