锵哥带你读好书系列之《深入浅出React和Redux》(第四章:模块化React和Redux应用)

造梦者之梦语:

很多事情努力了未必有结果,但是不努力却什么改变也没有。

故事旁白:

曾经有个少年,怀揣着一个梦,踏入一个叫做IT的圈子,从此明白江湖无容易二字。

社会如激流,如不勇进,终将被推下万丈深渊。

如果你能看到这篇文章,恭喜你,已经走到了第四章了,请坚持下去,会有收获的

主题预热:

本次锵哥将带大家了解一下,一个react项目,如何从一个应用的维度去思考跟设计,文章内容也会越来越开始深入,如果有心学,请认真阅读,这终将转化为你自己的能力筹码。

锵哥带你读好书系列之《深入浅出React和Redux》(第四章:模块化React和Redux应用)_第1张图片

正文:

章节:《深入浅出React和Redux》(第四章:模块化React和Redux应用)

1.创建一个复杂一点的应用该如何做:

A:模块化应用的要点

B:代码文件的组织方式

C:状态树的设计

D:开发辅助工具

2.从架构出发,当我们开始一个新的应用,有几件事情是一定要考虑清楚:

A:代码文件的组织结构

B:确定模块的边界

C:Store的状态树设计

3.确定了我们的应用要做什么之后,不要上来就开始写代码,磨刀不误砍柴工,先要考虑上面提到的三个问题。

4.代码文件的组织方式:

A:按角色组织

B:按功能组织

5.例如MVC按角色组织,分为controllers,models,views

6.Redux应用中有一种代码组织方式就是按角色组织,分为reducer(目录包含所有的Redux的reducer),actions(目录包含所有action构造函数),components(目录包含所有的傻瓜组件),contains(目录包含所有的容器组件)

7.在互联网上,很多教学资料也是按照“按角色组织”的方法管理Redux应用。虽然“按照角色组织”的方式看起来不错,但是实际上非常不利于应用的扩展。

8.Redux应用适合于“按功能组织”(Organzied by Feature),也就是把完成同一应用功能的代码放在一个目录下,一个应用功能包含多少个角色的代码。

9.每个目录包含角色文件:

A:actionTypes.js定义action类型

B:action.js定义action构造函数,决定了这个功能模块可以接受的动作

C:reducer.js定义这个功能模块如何响应action.js中定义的动作

D:views目录,包含这个功能模块中所有的React组件,包括傻瓜组件和容器组件

E:index.js这个文件把所有的角色导入,然后统一导出

10.表面上看来,“按照角色组织”还是“按照功能组织”只是一种审美的问题,也许你觉得自己已经习惯了MVC世界的“按照角色组织”方式,也许你已经有一套很厉害的代码编辑器可以完美解决在不同目录下寻找代码文件困难的问题。但是,开发Redux应用你依然应该“按照功能组织”的方式,为什么呢,我们看看下一条“确认模块的边界”就明白了

11.“在最理想的情况下,我们应该通过增加代码就能增加系统的功能,而不是通过对现有代码的修改来增加功能”

12.模块之间有依赖关系的时候,直接导入对方内部的文件非常不合理,因为这让filter模块依赖于todoList模块的内部结果,而且直接伸手到todoList内部去导入想要的部分

13.现在既然我们把一个目录看做一个模块,那么我们要做的是明确这个模块对外的接口,而这个接口应该实现把内部封装起来

14.如果filter中的组件想要使用todoList中的功能,应该导入todoList这个目录,因为导入一个目录的时候,默认导入的就是这个目录下的index.js文件,index.js文件中导出的内容,就是这个模块想要公开出来的接口

15.ES6语法中,export default和export两种导出方式的导入方式也会不同

16.无论使用哪种导出方式,都请在整个应用中只用一种模块导出方式,保持一致,避免混乱

17.因为所有的状态都存在Store上,Store的状态树设计,直接决定了要写那些reducer,还有action怎么写,所以是程序逻辑的源头

18.状态树设计要遵循几个原则:

A:一个模块控制一个状态节点

B:避免冗余数据

C:树形结构扁平

19.一个状态节点只属于一个模块,比如,如果A模块的reducer负责修改状态树上a字段下的数据,那么另一个模块B的reducer就不可能有机会修改a字段下的数据。

20.这里所说的“拥有权”指的是“修改权”,而不是“读取权”,实际上,Redux Store上的全部状态,在任何时候,对任何模块都是开放的,通过store.getState()总能够读取当前整个状态树的数据,但是只能更新自己相关那一部分模块的数据。

21.冗余数据是一致性的大敌,如果在Store上存储冗余数据,那么维持不同部分数据一致就是一个大问题

22.在前端Redux的Store中,一定要避免数据冗余的出现

23.即使使用“范式化”的无冗余数据结构,我们借助reselector等工具一样可以获得很高的性能

24.理论上,一个树形结构可以有很深的层次,但是我们在设计Redux Store的状态树时,要尽量保持树形结构的扁平

25.这是Redux最有意思的一部分,虽然Redux的createStore只接受一个reducer,却可以把多个reducer组合起来,成为一体,然后就可以被createStore函数接受

26.我们使用了Redux提供的一个函数combineReducers来把多个reducer函数合成为一个reducer函数

27.我们来总结一下Redux的组合reducer功能,利用combineReducers可以把多个只针对局部状态的“小的”reducer合并为一个操作整个状态树的“大的”reducer,更妙的是,没有两个“小的”reducer会发生冲突,因为无论怎么组合,状态树上一个子状态都只会被一个reducer处理,Redux就是用这种方法隔绝了各个模块

28.使用ref实际上就是直接触及了DOM元素,与我们想远离DOM是非之地的想法相悖,虽然React提供了这个功能,但是还是要谨慎使用,如果要用,我们也尽量让ref不要跨越组件的边界

29.我们并不能在JSX中使用for或者while这样的循环语句。因为JSX中可以使用任何形式的JavaScript表达式,只要JavaScript表达式出现在符号{}之间,但是也只能是JavaScript“表达式”,for或者while产生的是“语句”而不是“表达式”,所以不能出现for或者while

30.归根到底,JSX最终会被babel转译成一个嵌套的函数调用,在这个函数调用中自然无法插入一个语句进去,所以,当我们想要在JSX中根据数组产生动态数量的组件实例,就应该用数据的map方法。

31.实际上,Redux已经提供了一个bindActionCreators方法来消除这样的重复代码,显而易见很多mapDispatchToProps要做的事情只是把action构造函数和prop关联起来,所以直接以prop名为字段名,以action构造函数为对应字段值,把这样的对象传递给bindActionCreators就可以了。

32.更进一步,可以直接让mapDispatchToProps是一个prop到action构造函数的映射,这样连bindActionCreators函数都不用

33.我们使用了一个特殊的属性children,对于任何一个React组件都可以访问这样一个属性,代表的是被包裹住的子组件。

33.毫无疑问,ref的用法非常脆弱,因为React的产生就是为了避免直接操作DOM元素,因为直接访问DOM元素很容易产生失控的情况,现在为了读取某个DOM元素的值,通过ref获取对元素的直接引用,不得不说,干得并不漂亮

34.在产品开发中,应该尽量避免ref的使用,而换用这种状态绑定的方法来获取元素的值

35.开发辅助工具,Chrome扩展包

A:React Devtools,可以检视React组件的树形结构

B:Redux Devtools,可以检视Redux数据流,可以将Store状态跳跃到任何一个历史状态,也就是所谓的“时间旅行”功能

C:React Perf,可以发现React组件渲染的性能问题。

36.我们曾经反复强调过,每个reducer函数都必须是一个函数,不能修改传入的参数state和action,否则会让应用重新陷入状态不可预料的境地,

37.禁止reducer函数修改参数,这是一个规则,规则总是会被无心违反的,但是怎么避免开发者不小心违反这个规则呢,

38有一个redux-immutable-state-invariant包,提供了一个Redux的中间件,能够让Redux在每次派发动作之后做一个检查。如果发现某个reducer违反了作为一个纯函数的规定擅自修改了参数state,就会给一个大大的错误警告,从而让开发者意识到自己犯了一个错误,必须要修正

39.对于React Devtools来说,启用只是安装一个Chrome扩展包的事,但是对于其余几个工具,我们的代码要做一些修改才能配合浏览器使用

40.在这里把window赋值给模块级别变量win,是为了帮助代码缩小器(minifer),在webpack中缩小代码的插件叫UglifyJsPlugin,能够讲局部变量名改成很短的变量名,这样功能不受影响但是代码的大小大大缩减。

41.为了应用redux-immutable-state-invariant中间件和Redux Devtools,需要使用Redux的Store Enhancer功能。

42.因为Store Enhancer可能有多个,在我们的例子中就有两个,所以Redux提供了一个compose函数,用于把多个Store Enhancer组合在一起。

观后感回放:

粉丝路人甲:“锵哥今天好严肃,我怕”

锵哥:“别怕,当你发现看不懂的时候,就是你开始获得成长的时候”

粉丝路人甲:“嗯,我会坚持的”

锵哥:“加油!”

粉丝路人甲:“

广告:

本人从事全栈工程师,目前主要工作能力涵盖的范围有:android,ios,h5,pcWeb,react,vue,node,java服务端,微信服务号,微信小程序,支付宝生活号,支付宝小程序。

本公众号会不定期的将自己的研发感悟,以及心得笔记无私奉献给大家。还等啥,赶快上车吧,铁子们!!!(还会有其他的福利哦!快来吧)

官方订阅号:锵哥的觉悟

微信号:DY_suixincq

二维码:

你可能感兴趣的:(前端,react.js)