响应式系统与React | 青训营笔记
这是我参加【第四届青训营】笔记创作活动的第14天
今天学习响应式系统与React,在这之前我们需要了解一下前置知识,以便于我们更好地学习。
前置知识:
- HTML、JS、CSS基础;
- 基础的数据结构/算法知识,如二叉树、深度遍历等;
- 会使用浏览器提供的DOM API来修改DOM,更新UI。
01—React的历史与应用
01-1—React的应用场景
- 前端应用开发,如Facebook、Instagram、Netfix网页;
- 移动原生应用开发,如Instagram、Discord、Oculus;
- 结合Electron,进行桌面应用开发;
- 还可以用React写3D图形的库。
01-2—React的历史
2013年,React正式开源
02—React的设计思路
02-1—UI编程痛点
任何一种配置的改变,都会改变当前手机的价格,并反映在右上角的位置。
即每当用户点击一个卡片,都要更新右上角的价格。
如果没有React用js写,要声明一个js的变量,给上面的13pro放一个onClick事件,写一个callback
底下卡片也要放一个callback。任何一个callback被触发时,都要更新当前价格的变量currentValue。
再手动调用dom接口更新价格———过程式编程
总结:UI编程痛点
01—状态更新,UI不会自动更新,需要手动地调用DOM进行更新;
02—欠缺基本的代码层面的封装和隔离,代码层面没有组件化;
03—UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”。
02-2—响应式与转换式
转换式系统:
给定【输入】求解【输出】;
e.g.编译器;数值计算;
响应式系统:注重监听事件,事件发生后做事
监听事件,消息驱动;
e.g.监控系统;UI界面;
响应式系统
前端UI
02-3—响应式编程
01—状态更新,UI自动更新
“状态更新,UI不会自动更新,需要手动调节DOM进行更新”
02—前端代码组件化,可复用,可封装
“欠缺基本的代码层面的封装和隔离,代码层面没有组件化”
03—状态之间的互相依赖关系,只需声明即可
“UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”。”
02-4—组件化
注意:左侧结构不是DOM树。DOM树不是js内部的一个变量,DOM本身是浏览器内部维护的一个东西,只能通过调用js DOM的API去修改DOM。DOM与实际看到的UI存在一一对应的关系。左侧的划分是自己写代码时的一个划分
组件化应该遵循的准则总结:
- 组件是组件的组合/原子组件;
- 组件内拥有状态,外部不可见;
- 父组件可将状态传入组件内部。
状态归属问题
【当前价格】属于Root节点
状态归属于两个节点向上寻找最近的祖宗节点。共享只能往上放。
【当前价格】如何改变?
将onChangeValue()向下传递。
思考:
1、React是单向数据流还是双向数据流?单向数据流。父组件给子组件传东西。
2、如何解决状态不合理上升的问题?第五节
3、组件的状态改变后,如何更新DOM?第四节
组件设计
1、组件声明了状态和UI的映射;输入几个状态,反馈UI
2、组件有Props/State两种状态;内部State,外部Props
3、“组件”可由其他组件拼接而成
组件代码会是什么样子?
1、组件内部拥有私有状态State
2、组件接受外部的Props状态提供复用性
3、根据当前的State/Props,返回一个UI
生命周期
挂载-状态改变-卸载三种状态
03—React(hooks)的写法
用React封装好的函数更改状态才能做相应状态的刷新。setCount(count+1)
Live Coding
Hook使用法则:不要在循环,条件或嵌套函数中调用Hook。
04—React的实现
04-1—问题
01—JSX不符合JS标准语法
02—返回的JSX发生改变时,如何更新DOM
指令式编程:手动告诉程序需要怎么做。
声明式编程:发出指令自动做完。
响应式编程:自己响应自己。
虚拟DOM:更新状态—计算Diffing—Re-render
03—State/Props更新时,要重新触发render函数
04-2怎么去Diff?
TrafeOff权衡
完美的最小Diff算法,需要O(n^3)的复杂度。
牺牲理论最小Diff,换取时间,得到了O(n)复杂度的算法:Heuristic(启发式的) O(n) Algorithm
05—React的状态管理库
哪些东西适合放入状态管理库
准则:是否被整个app拥有的。e.g.当前用户的头像,每个组件都会使用
05-1—核心思想
05-2—推荐
05-3—状态机
05-4—Modern.js/Reduck
Live Coding