技本功丨知否知否,Redux源码竟如此意味深长(上集)

夫 子 说

元月二号欠下袋鼠云技术公号一篇关于Redux源码解读的文章,转眼月底,期间常被“债主”上门催债。由于年底项目工期比较紧,于是债务就这样被利滚利。但是好在这段时间有点闲暇,于是赶紧把这篇文章给完成了。据说文章点赞多了可以抵扣利息,小伙们要是觉得我这篇文章还不错的话,记得帮我点赞哦!好让我早日摆脱债务,感激不尽!

好了,回到正题。今天打算和大家讲一讲redux的源码,通过分析源码,我个人觉得受益匪浅,借此通过这篇文章把我的一些心得体会向大家分享一下,另外需要注意一下这次分享的源码用的redux的V4.0.0版本,小伙伴在对照的时候可别搞错咯。接下来老司机可是要发车了,大家抓紧时间上车哦!

在讲源码之前我们首先回顾一下redux是如何使用的,下面我们看一下使用demo:

上面这段代码完整地展示了redux的使用(如果有小伙伴对这段代码不是很理解的话,建议先去学习redux的使用再来看这篇源码,这样更加事半功倍)。通过上段代码,我们拆分几个比较核心的点,我一一列举一下:
1. action的结构是如何的?
2. 如何去定义一个reducer?
3. combineReducers是如何整合多个reducer的?
4. createStore是如何创建一个store?
5.dispatch拿到action到底干了什么?
6. subscribe是如何监听状态发生改变的?
7. getState是如何拿到所有的状态值的?
本期先解决前三个疑问,让我们一起去源码里寻找答案!
1、action的结构是如何的?
首先得解释一下action是干嘛的,它是负责把数据从应用带到store里面,也是store的唯一数据来源,并由以下两个部分组成:
1. type (操作类型)
2. payload (携带的数据)
为什么得有这两个?其实也很好理解,我们拿银行来类比。某天,你拿着一万块来到银行,走到柜台,人业务员第一件事肯定是问你要办啥业务,存钱?转账?还是还贷?你得把这些告诉业务员,不然业务没法给你办理业务,因此我们action就得有一个type,好让reducer知道你要干啥。当然,你办理存款或者是还款啥的,必不能少的就是毛爷爷了,payload对应的值就好比这些毛爷爷。用一个话来总结action的作用就是:告诉reducer拿着payload去做type这件事。
2、如何去定义一个reducer?
上面讲action的时候,提到了reducer了,这里还是拿我上面的银行做个类比,当我们拿着钱去银行存钱,我们不可能自己去银行把银行保险柜打开,完了把钱放进去,这样是不允许的,我们得需要业务员这个中间人去帮我们做存钱这件事,而业务员所扮演的角色正好就是reducer所要担任的角色。接下来讲一下如何去定义一个reducer,其实reducer的写法并没有绝对的写法,只要符合下面几个条件都能称之为reducer:
1. 必须得是一个函数。
2. 函数接收两个参数。第一个:该reducer所负责的state。第二个:action。
3. 函数体内部可以针对不同的action的type做出响应,这里你可以if-else或者switch-case都是可以的。
4. 函数必须有返回值。当修改state了之后,必须将修改后的state返回。如果遇到未知的type则需要返回一个默认值。
3、combineReducers是如何整合多个reducer的?
我们先看一下combineReducers传入的参数:

combineReducers接受的是一个参数首先得是对象,其次该对象每一个属性对应一个reducer。搞清楚combineReducers的结构之后,我们再看一下combineReducers对其做了哪些处理。
第一步:浅拷贝reducers

这里定义了一个finalReducers和finalReducerKeys,分别用来拷贝reducers和其属性。先用Object.keys方法拿到reducers所有的属性,然后进行for循环,每一项可根据其属性拿到对应的reducer,并浅拷贝到finalReducers中,但是前提条件是每个reducer的类型必须是Function,不然会直接跳过不拷贝。
第二步:检测finalReducers里的每个reducer是否都有默认返回值

assertReducerShape方法主要检测两点:
1. 不能占用redux内部特有的命名空间
2. 如果遇到未知的action的类型,reducer不能返回undefined,得返回默认的值
如果传入type为 @@redux/INIT<随机值> 的action,返回undefined,说明没有对未 知的action的类型做响应,需要加默认值。如果对应type为 @@redux/INIT<随机值> 的action返回不为undefined,但是却对应type为 @@redux/PROBE_UNKNOWN_ACTION_<随机值> 返回为undefined,说明占用了 命名空间。整个逻辑相对简单,好好自己梳理一下。
第三步:返回一个函数,用于代理所有的reducer

先对传入的state用getUnexpectedStateShapeWarningMessage做了一个异常检测,找出state里面没有对应reducer的key,并提示开发者做调整。接着我们跳到getUnexpectedStateShapeWarningMessage里,看其实现。

getUnexpectedStateShapeWarningMessage接收四个参数inputState(state)、reducers(finalReducers)、action(action)、unexpectedKeyCache(unexpectedKeyCache),这里要说一下unexpectedKeyCache是上一次检测inputState得到的其里面没有对应的reducer集合里的异常key的集合。整个逻辑如下:
1. 前置条件判断,保证reducers集合不为{}以及inputState为简单对象
2. 找出inputState里有的key但是 reducers集合里没有key
3. 如果是替换reducer的action,跳过第四步,不打印异常信息
4. 将所有异常的key打印出来
getUnexpectedStateShapeWarningMessage分析完之后,我们接着看后面的代码。

首先定义了一个hasChanged变量用来表示state是否发生变化,遍历reducers集合,将每个reducer对应的原state传入其中,得出其对应的新的state。紧接着后面对新的state做了一层未定义的校验,函数getUndefinedStateErrorMessage的代码如下:

逻辑很简单,仅仅做了一下错误信息的拼接。未定义校验完了之后,会跟原state作对比,得出其是否发生变化。最后发生变化返回nextState,否则返回state。
未完待续
下期预告
《技本功丨知否知否,Redux源码竟如此意味深长(下集)》
THE END
最后,
袋萌萌感谢每一位老铁2018年的陪伴,
生死看淡,不服就干
2019,咱们再战
不断进步

技本功丨知否知否,Redux源码竟如此意味深长(上集)的更多相关文章
- 技本功丨知否知否,Redux源码竟如此意味深长(下集)
上集回顾 Redux是如何使用的?首先再来回顾一下这个使用demo(谁让这段代码完整地展示了redux的使用) 如果有小伙伴对这段代码不是很理解的话,建议先去学习Redux的使用再来看这篇源码,这样更 ...
- 技本功丨收藏!斜杠青年与你共探微信小程序云开发(下篇)
2019年2月26日,人们为了一个杯子疯了一天. 星巴克猫爪杯,一场已经与猫无关了的“圣杯战争“.网上的倒卖价格,已炒至近千元! 求而不得,舍而不能,得而不惜.这是人最大的悲哀... 所以,请珍惜以下 ...
- 出售Illustrator脚本插件面板(包含面板源码,以及面板上所有的功能源码)
出售Illustrator脚本插件面板(包含面板源码,以及面板上所有的功能源码) 购买后可提供相应的小修改,以及教你使用往这个多列面里再加上按钮功能! 这套源码可作为工作使用,也可用为新手学习AI脚面 ...
- 技本功丨请带上纸笔刷着看:解读MySQL执行计划的type列和extra列
本萌最近被一则新闻深受鼓舞,西工大硬核“女学神”白雨桐,获6所世界顶级大学博士录取 货真价值的才貌双全,别人家的孩子 高考失利与心仪的专业失之交臂,选择了软件工程这门自己完全不懂的专业.即便全部归零, ...
- 基于MVVM的知乎日报应用安卓源码
使用data binding , dagger2 , retrofit2和rxjava实现的,基于MVVM的知乎日报APP运行效果: <ignore_js_op> 使用说明: 项目结构 a ...
- 第三方知乎专栏应用Android源码
这是一个国内开发者白瓦力贡献的一个简约的第三方知乎客户端,也许完整度不太高,但感觉还是相当不错的,其实我也是一个知乎迷,尽管平时围观的比较多. 我相信很多搞安卓开发的童鞋也去过知乎解惑吧.引用作者的描 ...
- 技本功丨利用 Atomic 构建 React 项目工作流,so easy!
近日刷微博,#2018年结婚率创新低#荣登热门话题NO.1,沪浙最不积极. 生活压力越大,缺爱的人也越来越多...据本萌的不完全观察,程序猿虽然是压力加成的职业,在袋鼠云还是有不少早早脱了单.至于,脱 ...
- 技本功丨用短平快的方式告诉你:Flink-SQL的扩展实现
2019年1月28日,阿里云宣布开源“计算王牌”实时计算平台Blink回馈给ApacheFlink社区.官方称,计算延迟已经降到毫秒级,也就是你在浏览网页的时候,眨了一下眼睛,淘宝.天猫处理的信息已经 ...
- 知乎日报客户端应用ios源码
swift开发的知乎日报客户端详细源码,里面分UI和网络两个模块. 1.涉及到了大部分的UI控件的使用(甚至包括UIRefreshView,UITableConrol等等)2.Connection完成 ...
随机推荐
- 使用Vue构建单页应用一
一. 环境准备 1 安装Node.js 最好安装node.js-6.X.X 以上版本,https://nodejs.org/en/ 我使用的是 v6.3.1 Current 版本.Node. ...
- CSS 高级选择器
相信各位如我一样的“抠图崽”和前端大佬们,在写网页样式的实话,总是免不了写下各种各样的选择器,再给选择的元素写入样式.最基本的元素选择器.class选择器.ID选择器等就不再过多的说了,相信大家都熟的 ...
- 阿里前端测试题--关于ES6中Promise函数的理解与应用
今天做了阿里前端的笔试题目,原题目是这样的 //实现mergePromise函数,把传进去的数组顺序先后执行,//并且把返回的数据先后放到数组data中 const timeout = ms => ...
- Flask—08-建立自己的博客(02)
博客项目 上一篇内容完善 自定义字段验证函数 class RegisterForm(FlaskForm): ... def validate_username(self, field): user = ...
- LeetCodee 105. Construct Binary Tree from Preorder and Inorder Traversal
问题重述: 问题求解: 我们换一组比较有代表性的样例, 对于上图的树来说, index: 0 1 2 3 4 5 6 先序遍历为: 中序遍历为: 5同理,右子树也是如此.这样不难看出本题应该用递归方法 ...
- OC - ARC(自动引用计数)
1.什么是自动引用计数? 顾明思义,自动引用计数(ARC,Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术. 在OC中采用ARC机制,让编译器来进行内存 ...
- linux下的学习之路下的小困难
centos下源码安装python3wget --no-check-certificate https://www.python.org/ftp/python/3.6.2/Python-3.6.2.t ...
- dmesg功能介绍
dmesg 命令的使用范例 ‘dmesg’命令设备故障的诊断是非常重要的.在‘dmesg’命令的帮助下进行硬件的连接或断开连接操作时,我们可以看到硬件的检测或者断开连接的信息.‘dmesg’命令在多数 ...
- Jquery拼图
Jquery代码 <script> $(function () { $("td").click(function () { var img = $(this).prop ...
- python学习笔记(3)---cookie & session
一.cookie & session 1.cookie: cookie 就是由服务器发送给客户端的特殊信息,而这些信息以文本的方式存放在客户端,然后客户端每次向服务器发送请求都会带上这些特殊信 ...