沉浸式剧情引导:
粉丝路人甲:“锵哥,经过前面两章,我了解了 react 的新的前端思维方式,还有如何设计一个高质量的组件,今天是什么菜?”
锵哥:“坐稳了,我们的飞机要开始起飞了,系好安全带!分了神容易迷路了,咱们要升级难度了”
粉丝路人甲:“系好了,锵哥请带路!”
锵哥:“我们知道组件如果要接受外部的状态,是通过 prop 属性传递的,如果一个父组件里面有层次很深的子组件要接受父组件的状态怎么办?”
粉丝路人甲:“我就一层层传递进去可以不?”
锵哥:“可以是可以,但是很不优雅,也极其的难以维护。”
粉丝路人甲:“那咋办呀?”
锵哥:“我们需要借助 Store(Store 是 react 应用中全局存取数据的地方),父组件操控改变 Store 中的某个变量如变量 A,子组件获取 Store 变量 A 的值并显示变量 A,这样一来,就从复杂的嵌套关系中解脱出来,扁平化了”
粉丝路人甲:“原来是这样啊,听起来很简单嘛,有什么需要注意的吗?”
锵哥:“编程需要遵守规则,Store 的值改变也是有规则,有自己的玩法,我们需要了解一下 Flux 和 Redux,它们是一种架构思想,它们能帮我们更优雅的管理 Store,构建更健壮的 React 应用”
粉丝路人甲:“锵哥我们起飞吧,我准备好了”
正文:
章节:《深入浅出 React 和 Redux》(第三章:从 Flux 到 Redux)
1. 一个 Flux 应用包含四个部分,我们先粗略了解一下:
A:Dispatcher,处理动作分发,维持 Store 之间的依赖关系
B:Store,负责存储数据和处理数据相关逻辑
C:Action,驱动 Dispatcher 的 JavaScript 对象
D:View,视图部分,负责显示用户界面
2. 我们只是把 register 函数的返回值保存在 CounterStore 对象的 dispatchToken 字段上,待会就会用到(这个设计是 Flux 一个弊端)。
3. 在 Flux 的理念里,如果要改变界面,必须改变 Store 中的状态,如果要改变 Store 中的状态,必须派发一个 action 对象,这就是规矩。在这个规矩之下,想要追溯一个应用的逻辑就变得非常容易。
4.Flux 这个设计的确解决了 Store 之间的依赖关系,但是,这样明显的模块之间的依赖,看着还是让人感觉不大舒服,毕竟,最好的依赖管理是笨笨不让依赖产生
A:CounterStore 必须要把注册回调函数时产生的 dispatchToken 公之于众
B:SummaryStore 必须要在代码里建立对 CounterStore 的 dispatchToken 的依赖
5. 在 Flux 的体系中,有一个全局的 Dispatcher,然后每一个 Store 都是一个全局唯一的对象,这对于浏览器端应用完全没有问题,但是如果放在服务器端,就会有大问题。(Flux 不是设计用作服务器端渲染的,他们也从来没有尝试过把 Flux 应用于服务器端)。
6.Flux 的基本原则是“单向数据流”,Redux 在此基础上强调三个基本原则:
A: 唯一数据源(Single Source of Truth)
B: 保持状态只读(State is read-only)
C: 数据改变只能通过纯函数完成(Changes are made with pure functions)
7. 唯一数据源指的是应用的状态数据应该只存储在唯一的一个 Store 上。
8. 保持状态只读,就是说不能直接修改状态,要修改 Store 的状态,必须要通过派发一个 action 对象完成,这一点,和 Flux 的要求并没有什么区别。
9. 数据改变只能通过纯函数完成,这里所说的纯函数就是 Reducer,Redux 这个名字的前三个字母 Red 代表的就是 Reducer。按照创作者 Dan Abramoy 的说话,Redux 名字的含义是 Reducer+Flux。
10. 和 Flux 很不一样的是,在 reducer 中,绝对不能去修改参数中的 state,如果我们直接修改 state 并返回 state 是不正确的写法,像上面这样写,似乎更简单直接,但实际上犯了大错,因为 reducer 应该是一个纯函数,纯函数不应该产生任何副作用。
11. 在 Redux 框架下,一个 React 组件基本上就是要完成以下两个功能
A: 和 Redux Store 打交道,读取 Store 的状态,用于初始化组件的状态,同时还要监听 Store 的状态改变;当 Store 状态发生变化时,需要更新组件状态,从而驱动组件重新渲染;当需要更新 Store 状态时,就要派发 action 对象
B: 根据当前 props 和 state,渲染出用户界面
12 承担第一个任务的组件,也就是负责和 Redux Store 打交道的组件,处于外层,所以被称为容器组件(Container Component);对于承担第二个任务的组件,也就是只专心负责渲染界面的组件,处于内层,叫做展示组件(Presentational Component)。
13. 外层的容器组件又叫聪明租金(Smart Component),内层的展示组件又叫傻瓜组件(Dumb Component),所谓“聪明”还是“傻瓜”只是相对而言,并没有褒贬的含义。
14. 傻瓜组件就是一个纯函数,根据 props 产生结果。说是“傻瓜”,我倒是觉得这种纯函数实现反而体现了计算机编程中的大智慧,大智若愚。
15. 而容器组件,只是做的事情涉及一些状态转换,虽然名字里有“聪明”,其实做的事情都有套路,我们很容易就能抽取出共同之处,复用代码完成任务,并需要开发者极其聪明才能掌握。
16.Counter 组件完全没有 state,只有一个 render 方法,所有的数据都来自于 props,这种组件叫做“无状态”组件。
17. 因为没有状态,不需要用对象表示,所以连类都不需要了,对于一个只有 render 方法的组件,缩略为一个函数足矣。
18.React 提供了一个叫 Context 的功能,能够完美的解决 props 传递 store 这种不好设计问题。
19. 所谓 Context,就是“上下文环境”,让一个树状组件上所欲组件都能访问一个共同的对象,为了完成这个任务,需要上级组件和下级组件配合
A: 首先,上级组件要宣称自己支持 context,并且提供一个函数来返回代表 Context 的对象
B: 然后,这个上级组件之下的所有子孙组件,只要宣称自己需要这个 Context,就可以通过 this.context 访问到这个共同的环境对象
20. 我们来创建一个特殊的 React 组件,他将是一个通用的 context 来提供者,可以应用在任何一个应用中,我们把这个组件了叫做 Provider。
21.Provider 还要提供一个函数 getChildContext,这个函数返回的就是代表 Context 的对象。
22.Provider 还需要定义类的 childContextTypes,必须和 getChildContext 对应,只有这两者都齐备,Provider 的子组件才有可能访问到 context。
23.react-redux 的两个最主要功能
A:connect:连接容器组件和傻瓜组件
B:Provider:提供包含 store 的 context。
24. 作为容器组件,要做的工作无外部两件事
A: 把 Store 上的状态转化为内层傻瓜组件的 prop
B: 把内层傻瓜组件的用户动作转化为派送给 Store 的动作
25.react-redux 要求 store 不光是一个 object,并且是必须包含三个函数的 object,这三个函数分别是
A:subscribe
B:dispatch
C:getState
拥有上述三个函数的对象,才能称之为一个 Redux 的 store。
观后小剧场:
粉丝路人甲:“涨姿势了!”
锵哥:“一步步来,掌握了规则,熟悉了玩法,才能成为一个正规的玩家”
粉丝路人甲:“有道理,好期待明天的内容呀”
锵哥:“欲知后事如何,请听下回书,关注一波,一手资讯”
粉丝路人甲:“扫!扫!!扫!!!”
广告:
本人从事全栈工程师,目前主要工作能力涵盖的范围有:android,ios,h5,pcWeb,react,vue,node,java 服务端,微信服务号,微信小程序,支付宝生活号,支付宝小程序。
本公众号会不定期的将自己的研发感悟,以及心得笔记无私奉献给大家。还等啥,赶快上车吧,铁子们!!!????(还会有其他的福利哦!快来吧)
官方订阅号:锵哥的觉悟
微信号:DY_suixincq
二维码: