前言
看完 Redux文档,对Redux的内部运作不是很了解,大致问题记录如下:
- 容器组件怎么通过connect将store里的数据传入展示型组件的props中?
- mapStateToProps与mapDispatchToProps怎么将state与dispatch的值组装到props?
- action是什么?dispatch action做了些什么操作?
- 若dispatch 一个函数,则函数默认参数有dispatch与state,自定义的函数怎么能默认接受这两个参数的?
带着这些问题打开Redux源码,发现才一年的时间没做前端,Redux源码都从js换成ts了,屁颠屁颠跑去看TS文档,没咋看懂,但是应该能上源码了。
源码结构
首先看看文件夹目录结构
几个常用的api都在src/下,再下一级目录就是封装的一些类型,这些后面再详细描述,先开始上源码!
index.ts
这个文件主要导出了一些常用的接口
import createStore from './createStore'
import combineReducers from './combineReducers'
import bindActionCreators from './bindActionCreators'
import applyMiddleware from './applyMiddleware'
import compose from './compose'
import warning from './utils/warning'
import __DO_NOT_USE__ActionTypes from './utils/actionTypes'
//中间省略一些代码
···
export {
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose,
__DO_NOT_USE__ActionTypes
}
可以看到我们Redux里常用的api,createstore、combineReducers、applyMiddleware、compose都给导出了,bindActionCreators之前没有用到过,正好可以看一下实现和用法。
按照导出顺序挨个看看这些文件
createStore.ts
这个文件重载了两个createStore方法,主要区别是有无 preloadedState 这个参数。
export default function createStore<
S,
A extends Action,
Ext = {},
StateExt = never
>(
reducer: Reducer<S, A>,
enhancer?: StoreEnhancer<Ext, StateExt>
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
export default function createStore<
S,
A extends Action,
Ext = {},
StateExt = never
>(
reducer: Reducer<S, A>,
preloadedState?: PreloadedState<S>,
enhancer?: StoreEnhancer<Ext, StateExt>
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
用UML画了个假装是createStore的类图,主要是为了方便看这个函数里面定义的一些属性和方法。
函数申明
export default function createStore<
S,
A extends Action,
Ext = {},
StateExt = never
>(
reducer: Reducer<S, A>,
preloadedState?: PreloadedState<S> | StoreEnhancer<Ext, StateExt>,
enhancer?: StoreEnhancer<Ext, StateExt>
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
这个函数接收两到三个参数,其中,若只传入两个参数,且第二个参数为函数,会把第二个参数preloadedState赋值给enhancer,然后preloadedState赋值为undefined。
if (
(typeof preloadedState === 'function' && typeof enhancer === 'function') ||
(typeof enhancer === 'function' && typeof arguments[3] === 'function')
) {
throw new Error(
'It looks like you are passing several store enhancers to ' +
'createStore(). This is not supported. Instead, compose them ' +
'together to a single function.'
)
}
// 这里,其他都是类型检测
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState as StoreEnhancer<Ext, StateExt>
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(
reducer,
preloadedState as PreloadedState<S>
) as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
}
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.')
}
然后就是方法内其他函数的介绍
dispatch(action)
该方法主要做了如下三个操作:
1、修改 isDispatching的值(定义这个有点类似于锁的思想,阻止其他操作的修改)。
2、计算属性currentState的值,该值通过getState()方法获取
3、执行listeners[]数组里的每个listener方法。
4、返回action(这个action为函数传入的action)
代码如下:
function dispatch(action: A) {
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
}
const listeners = (currentListeners = nextListeners)
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i]
listener()
}
return action
}