redux是我阅读知名库源码的迈开的第一步,2年前结合函数式编程思想也总结过redux源码阅读笔记。但是当时没有将整个体系串起来弄清楚。现在再读,redux简洁明了的源码真是感人,整个流程特别容易理解了。
redux
核心能力:提供数据存储,分发、变更的机制。意在管控数据流的变更,让一切变更可感知,配合单向数据流。
包含createStore、applyMiddleware、bindActionCreator、combineReducer四个组成部分,也是对外提供的api。其中bindActionCreator、combineReducer为辅助工具。
createStore
核心的createStore提供获取state的getState方法和变更数据的dispatch方法,applyMiddleware提供的中间件组装机制,能让中间件在数据变更前进行对应处理,这个阶段可以更改state,中间件可以封装出更有能力的dispatch。
dispatch的能力是调用reducer函数传入oldState和action获得最新的state, 并且调用store.subscribe注册的listeners。- getState则直接返回createStore里的局部变量currentState
如果有enhancer如调用中间件的applyMiddleware,则将当前函数作为参数传给applyMiddleware处理。否则,构造出getState\dispatch返回

applyMiddleware
真正调用createStore获得dispatch和getState,给每个中间件注入这2个接口
dispatch的封装
dispatch: function dispatch(action){
return _dispatch(action);
}
这种写法是为了保证是middleware第一层获取到的dispatch是最初来自createStore的的dispatch,而后面_dispatch=compose.apply(undefined, chain)(store.dispatch)的dispatch则是被中间件包装处理的含有各种功能的dispatch。而这一步正是调用下面redux thunk中createThunkMiddleware封装的dispatch的地方:
可以看出next就是compose组合的各个中间件函数。
redux中间件
中间件可以接受dispatch和getState函数,且必须返回action, 格式:
function middleware(){
return ({dispatch, getState}) => next => action => {
//封装action
return action
}
}
这个函数式的经典风格其实挺绕的,第一层是在applyMiddleware里调用middleware(middlewareAPI)消费,第二层next是applyMiddleware的compose获取封装的dispatch时消费,第三层action是最终action触发dipatch调用时消费。
applyMiddleware的调用时机
createStore的调用有2种格式:
无论哪一种,最终经过内部逻辑后都是一样的后续流程。最后一个参数就是enhancer,最终会调用enhancer(createStore)(reducer, preloadedState)
所以applyMiddleware里的第一层return (createStore) => {}在这里调用,第二层也紧接着被调用。
可以看出,applyMiddleware作用是获取各个中间件封装后的最终dispatch并和原始store一起返回。

bindActionCreator
调用姿势:
connect(
(state) => {
return {
compName :state.compNameState,
}
},
(dispatch) => {
return {
actions: bindActionCreators(compNameAction, dispatch)
}
}
)(comp, compNameAction);
这里connect来源于react-redux, bindActionCreators来源于redux。
将action函数用dispatch封装一层,视图层就不需要再传入dispatch了。bindActionCreators中的dispatch来源于视图层<provider>中注入的store里的dispatch

redux-thunk
为了解决频繁出现的异步action的需求,redux-thunk也是必不可少的库

当有异步等需要处理时,我们写aciton时格式是:
function actionFn(){
return (dispatch, getstate) => {
return dispatch(otherFn)
}
}
这样就能将redux-thunk注册的dispatch和getState给内部层层调用,直到最终dipatch获得的是简单的对象型action,走next(action)。这里的next如果有中间件,会进入中间件里。

中间件里的next指向下一个中间件:store => next => action => { //handler }
react-redux
可以看到redux虽然总是被用在react的生态体系内,但是其实他们没有绑定关系,redux完全是个独立的管理数据的库。要和react配套使用,要react-redux来作为连接桥梁。
理解了这个库的作用才理解了react和redux那一套是怎么闭环的。
它的实现是将redux store里记录的state 注入到组件里,通过提供Provider和高阶组件Connect来连接。
Provider
Provider仅仅是获取到createStore创建出的store对象供自己调用,再传递到内部组件,实现让开发者写的组件能通过props获取到redux管理的数据。

Connect:
通过调用store.subcribe来监听state的变更,在state变更时对自己的组件setState,从而达到更新视图获取组件的state
还会有mapStateToProps、mapDispatchToProps来分发只记录被过滤的reducer和action作为当前组件的state
其他一坨判断都是更新之类的把控

