深入浅出Redux(二):Redux源码梳理

组内技术生态是React,参与使用React构建的大型项目也有几个了,趁着最近需求比较不饱和,来梳理一下常和React配套使用的数据流框架Redux的使用方法和内部原理。

阅读本文可以了解

  1. redux简单源码梳理

源码梳理

看一眼github中的源码文件

2018-06-21-17-01-55

1、index

没什么好说的,就是将方法导出

1
2
3
4
5
6
7
export {
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose
}

2、createStore

这个方法比较重要,用于一开始创建应用唯一Store。来看看关键代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default function createStore(reducer, preloadedState, enhancer) {
let currentReducer = reducer // 传入的reducer
let currentState = preloadedState // 传入的初始化state
let currentListeners = [] // 传入的监听函数
let nextListeners = currentListeners // 用于后面真拷贝一个currentListeners数组
function getState() {
...
}
function subscribe(listener) {
...
}
function dispatch(listener) {
...
}
// 返回store对象,后续可直接调用store.xxx
return { getState, dispatch, subscribe }
}

3、store.dispatch

1
2
3
4
5
6
7
8
9
10
11
12
function dispatch (action) {
// 执行reducer
currentState = currentReducer(currentState, action)
// 执行监听函数
const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}

4、store.subscribe

订阅监听函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function subscribe (listener) {
// subscribe时保存一份快照:确保在subscribe内部再次subscribe或者unsubscribes时数据的确定性
// 注意到dispatch时调用的是currentListeners里面的listener,那么才可能随时修改nextListeners
ensureCanMutateNextListeners()
nextListeners.push(listener)
// 返回新函数用以移除监听函数
// unlistener1 = store.subscribe(listener)
// unlistener1()
return function unsubscribe () {
ensureCanMutateNextListeners()
const index = nextListeners.indexOf(listener)
// 在nextListeners中取消订阅当前的监听函数
nextListeners.splice(index, 1)
}
}
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}

5、store.getState

非常简单,没什么好说的

1
2
3
function getStore () {
return currentState
}

6、combineReducers

combineReducers()做的就是产生一个整体的 Reducer 函数。该函数根据 State 的 key 去执行相应的子 Reducer,并将返回结果合并成一个大的 State 对象。

1
2
3
4
```
### 7、bindActionCreators
这个函数就是为我们省去了手动dispatch(action)这一步,简单看一下函数

// 单个actionCreator包裹
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}

// 多个
// 其实就是循环执行bindActionCreator
export default function bindActionCreators(actionCreators, dispatch) {
const keys = Object.keys(actionCreators)
const boundActionCreators = {}
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const actionCreator = actionCreators[key]
if (typeof actionCreator === ‘function’) {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
```

未完待续。。感谢阅读

2018-06-27-11-26-50