1. redux中三个常见的方法
- getState(),用来获取state对象树
- dispatch(),分发同步action
- subscribe(),绑定监听,当state树中某些属性发生改变的时候,调用回调函数,重新渲染
/**
* 首先,该函数的返回值是一个对象,因为在调用的时候都是 store.getState(),所以返回的对象中有是三个属性的属性值必然是函数
*/
export function createStore(reducer) {
let state // 保存state对象树
const listeners = [] // 保存所有的subscribe的回调函数
state = reducer(state, {type: '@mini'})
function getState() {
return state
}
function dispatch(action) {
// 将reducer函数得到的新的state数替换掉原来的state
state = reducer(state, action)
// 将所有subscribe的回调函数调用,来达到重新渲染的效果
listeners.forEach(listener => {
listener()
})
}
// 将所有的调用subscribe的回调函数保存起来,当调用dispatch改变属性状态时,将所有subscribe的回调函数调用,来达到重新渲染的效果
function subscribe(listener) {
listeners.push(listener)
}
return {getState, dispatch, subscribe}
}
2.redux库中第二个重要的东西,整合多个reducer的函数(combinReducers)
需要注意的是:整合所有 reducer 的函数,他自己本身还是一个 reducer。所有该函数的返回值就是一个 reducer函数
代码:
export function combineReducers(reducers) {
// 因为返回的是一个reducer函数,所以该函数存在 state 和 action 的参数,其中 state为总的 state 树,action 为 dispatch传入的 action
/**
* state = {
* count: 0,
* msgs: []
* }
*/
return function (state = {}, action) {
// 因为处理每个reducer函数,返回的值都是该reducer函数的新的state,那么最后所有的子state就要组成一个新的state树,该对象就是用来保存最后返回的新的state总树
const newState = {}
// 因为传入 combineReducers 的是一个对象,且每个属性的属性值都是一个以属性名来命名的reducer函数,所有key通过遍历得到所有的键名,每个键名也就是每一个reducer的函数名
const keys = Object.keys(reducers)
// 再遍历该键名组成的数组
keys.forEach(key => {
// 找到每一个子的reducer函数
const childReducer = reducers[key]
// 因为每个函数都是一个reducer函数,所有需要一个 state对象和一个同步 action,同步 action是用户传入的,而子state就是总state上的一个属性
const childState = state[key]
// 调用子reducer函数,返回的结果是一个新的子state
const newChildState = childReducer(childState, action)
// 将新的子state存入最后需要返回的新的总state中
newState[key] = newChildState
})
return newState
}
}
将上面的代码简化一下:
export function combineReducers(reducers) {
return function (state = {}, action) {
return Object.keys(reducers).reduce((newState, reducerName) => {
newState[reducerName] = reducers[reducerName](state[reducerName], action)
return newState
}, {})
}
}