redux源码详解

redux是基于flux单向数据流的一种实现,功能很强大,源码很精炼,可以扩展出各种中间件,so 酷。

createStore.js

这个文件其实很简单,首先我们来看一下它接受的参数。


function createStore(reducer, initialState){

}

这里的reducer就是 combineReducers后的rootReducer,当我们dispatch一个action的时候


function dispatch(action) {
currentState = currentReducer(currentState, action)
}

currentReducer接受了两个参数,currentState,也就是当前的state。和我dispatch的action,当返回的action.type匹配到相应的reducer时,就会更新store。
在createStore.js文件的返回值中,最常用的应该是dispatch和getState()。
其中dispatch用来分发action到reducer从而更新store, 而getState() 方法则会拿到当前的store。

combineReducers.js

首先我们来讨论一下为什么会有这个文件。首先我们不会把整个项目的reducer都写在一个switch里。
所以我们可能会写多个reducer,但是当我们调用createStore()方法来生成store时,就会调用多个createStore。好的,这样问题就来了,不但会产生多个数据源,而且会有多个dispatch,getState()等等。
而combineReducer就是为了解决上面的一系列问题而存在的。


function combination(state=defaultState, action) {
var finalState = mapValue(finalReducers, 
(reducer, key) => {
var previousStateForKey = state[key];
var nextStateForKey = reducer(previousStateForKey, action);
return nextStateForKey;
})
return finalState
}

这里只列出了主要的几行代码,其中mapValue()方法会把finalReducers的函数名映射到state[key]中,从而在整个store树中产生一个新的节点,所以reducer里面的state不再是全局的state而只是它的一个节点,这样当我们在reducer里更新state的时候不必在关心其它的reducer只关注自己当前的这个state就可以了。

applyMIddleware.js

关于applyMiddleware,就是调用中间件,听起来貌似很高大上,实际上的代码实现却是非常简单。
所谓中间件,就是将dispatch(action)和getState()方法不断的在中间件方法中传递,最后再传递给reducer。先来看一下代码实现。


function applyMiddleware(...middlewares) {
var middlewareAPI = {
getState = store.getState,
dispatch: (action) => dispatch(action)
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch);
}
}

其中compose是redux自己的一个工具函数



function compose(...funcs) {
return arg => funcs.reduceRight((composed, f) => f(composed), arg);
}   

what?毛线啊这是?
读书少,没办法,要去看看复合函数和柯里化的概念了。
首先我们回过头来看一下这个方法的调用模式

dispatch = compose(...chain)(store.dispatch);

其中store.dispatch参数就是compose方法中的age。
柯里化是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术,这里正是用到了函数式编程的柯里化。举个例子



function sum(num){ 
return function (x){ 
return num + x; 
} 
} 
var sum1 = sum(1)(1); 
var sum2 = sum(2)(1); 
console.log(sum1); //2
console.log(sum2); //3

回到主题,compose方法组合了我们的的中间件链
在redux中的中间件模式,可以让我们处理多种类型的action,当然其中最为常用的可能就是异步的action。先来看一下异步中间键reduxthunk的实现。
其调用模式类似于

middlewareA(middlewareB(middlewareC(store.dispatch)))(action)


function thunkMiddleware({ dispatch, getState }) {
return next => action =>
typeof action === 'function' ?
action(dispatch, getState) :
next(action);
}
module.exports = thunkMiddleware

骗子。。。当我兴致勃勃的去看源码的时候,整个库真的居然只有这么几行有用的代码,好吧,这里其实就是判断了action是不是一个function如果时的话就将dispatch和getState交给这个action来处理。

总结

其实吧,我一直都觉得redux的流程是很繁琐的,但是它的优点却是更加明显,single store使整个项目的数据结构更佳清晰。避免项目很大时,数据以及状态难以维护和管理情况。

                                  杏树林研发 武鹏宇
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值