一.createStore的接收值和返回值
1.createStore接收3个值:
1.reducer
2.preloadedState:仓库的初始状态
3.enhancer:applyMiddleware返回的函数
export default function createStore(reducer, preloadedState, enhancer) {
let currentReducer = reducer // 仓库的reducer
let currentState = preloadedState // 仓库当前的状态
let currentListeners = [] // 存储监听器的数组
let nextListeners = currentListeners
let isDispatching = false
return {
dispatch,
subscribe,
getState,
replaceReducer,
[$$observable]: observable
}
}
2.createStore的返回值:
1.dispatch:用来分发action
2.getState:获取仓库中当前的状态
3.replaceReducer:替换当前的reducer
4.subscribe:注册监听器,当分发action的时候,会运行监听器,该函数会返回一个函数,用于取消监听器
5.Symbol(observable):观察者模式
二.getState
直接返回当前的仓库状态currentState
源码:
function getState() {
if (isDispatching) {
throw new Error(
'You may not call store.getState() while the reducer is executing. ' +
'The reducer has already received the state as an argument. ' +
'Pass it down from the top reducer instead of reading it from the store.'
)
}
return currentState
}
三、dispatch
dispatch接收一个参数action
1.action必须是一个平面函数
2.传入的action必须要有一个type值
3.通过reducer获取到新的状态
4.循环运行所有监听器
源码:
function dispatch(action) {
// 判断是不是平面对象
if (!isPlainObject(action)) {
throw new Error(
'Actions must be plain objects. ' +
'Use custom middleware for async actions.'
)
}
// 传入的action必须要有个type值
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
// 通过reducer返回新的状态state
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
}
四、创建仓库的时候需要调用一次dispatch
原因:调用一个dispatch让仓库初始化
传入的action的type是一个特殊的值@@redux/INIT+随机数
源码:
// 生成随机数
const randomString = () =>
Math.random()
.toString(36)
.substring(7)
.split('')
.join('.')
// action的type
const ActionTypes = {
INIT: `@@redux/INIT${randomString()}`
}
// 创建仓库的时候默认触发一次dispatch
dispatch({ type: ActionTypes.INIT })
五、subscribe
传入一个函数listener,创建一个监听器,把监听器添加到监听器数组中,在dispatch改变仓库状态后触发,最后返回一个函数用于取消监听器
源码:
function subscribe(listener) {
// 传入的listener必须是一个函数
if (typeof listener !== 'function') {
throw new Error('Expected the listener to be a function.')
}
if (isDispatching) {
throw new Error(
'You may not call store.subscribe() while the reducer is executing. ' +
'If you would like to be notified after the store has been updated, subscribe from a ' +
'component and invoke store.getState() in the callback to access the latest state. ' +
'See https://redux.js.org/api-reference/store#subscribelistener for more details.'
)
}
// 用于判断当前是否已经移除该监听器
let isSubscribed = true
ensureCanMutateNextListeners()
// 添加监听器到数组中
nextListeners.push(listener)
// 返回一个函数用于取消监听器
return function unsubscribe() {
// 判断是否已经移除了监听器
if (!isSubscribed) {
return
}
if (isDispatching) {
throw new Error(
'You may not unsubscribe from a store listener while the reducer is executing. ' +
'See https://redux.js.org/api-reference/store#subscribelistener for more details.'
)
}
isSubscribed = false
ensureCanMutateNextListeners()
// 获取当前监听器的下标
const index = nextListeners.indexOf(listener)
// 从监听器数组中删除监听器
nextListeners.splice(index, 1)
currentListeners = null
}
}
六、replaceReducer
接收一个reducer用于替换当前的reducer
替换之后触发一次dispatch
源码:
const ActionTypes = {
REPLACE: `@@redux/REPLACE${randomString()}`,
}
function replaceReducer(nextReducer) {
// 传入的reducer必须是一个函数
if (typeof nextReducer !== 'function') {
throw new Error('Expected the nextReducer to be a function.')
}
// 替换当前的reducer
currentReducer = nextReducer
// 替换后触发一次dispatch
dispatch({ type: ActionTypes.REPLACE })
}
七、enhancer
enhancer是applyMiddleware返回的函数,记录了所有的中间件返回的dispatch创建函数
// createStore可以传入二个参数或者三个参数
// 如果传入两个参数 可以是reducer和preloadedState 或者 reducer和enhancer
// 如果第二个参数和第三个参数都为函数 或者 enhancer 和后面的第4个参数都为函数
// 说明用户可能想传入多个中间件 直接报错让用户通过compose(applyMiddleware)整合函数
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.'
)
}
// 如果preloadedState为函数 enhancer为undefined说明用户没有传入默认的仓库状态 直接传入了applyMiddleware返回的函数
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
// 如果enhancer不是undefined 且是一个函数 直接通过enhancer(applyMiddleware的返回函数)创建仓库
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
return enhancer(createStore)(reducer, preloadedState)
}