响应式系统与React | 青训营笔记

90 阅读4分钟

响应式系统与React | 青训营笔记

这是我参加【第四届青训营】笔记创作活动的第14天

今天学习响应式系统与React,在这之前我们需要了解一下前置知识,以便于我们更好地学习。

前置知识:

  • HTML、JS、CSS基础;
  • 基础的数据结构/算法知识,如二叉树、深度遍历等;
  • 会使用浏览器提供的DOM API来修改DOM,更新UI。

01—React的历史与应用

01-1—React的应用场景

image-20220807103032030.png

  • 前端应用开发,如Facebook、Instagram、Netfix网页;
  • 移动原生应用开发,如Instagram、Discord、Oculus;
  • 结合Electron,进行桌面应用开发;
  • 还可以用React写3D图形的库。

01-2—React的历史

image-20220807103112805.png

2013年,React正式开源

image-20220807103124337.png

image-20220807103301306.png

02—React的设计思路

02-1—UI编程痛点

image-20220807103352485.png

任何一种配置的改变,都会改变当前手机的价格,并反映在右上角的位置。

即每当用户点击一个卡片,都要更新右上角的价格。

如果没有React用js写,要声明一个js的变量,给上面的13pro放一个onClick事件,写一个callback

底下卡片也要放一个callback。任何一个callback被触发时,都要更新当前价格的变量currentValue。

再手动调用dom接口更新价格———过程式编程

image-20220807103409268.png

总结:UI编程痛点

01—状态更新,UI不会自动更新,需要手动地调用DOM进行更新;

02—欠缺基本的代码层面的封装和隔离,代码层面没有组件化;

03—UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”。

02-2—响应式与转换式

image-20220807103655877.png

转换式系统:

给定【输入】求解【输出】;

e.g.编译器;数值计算;

响应式系统:注重监听事件,事件发生后做事

监听事件,消息驱动;

e.g.监控系统;UI界面;

响应式系统

image-20220807103843157.png

前端UI

image-20220807103903698.png

02-3—响应式编程

01—状态更新,UI自动更新

“状态更新,UI不会自动更新,需要手动调节DOM进行更新”

02—前端代码组件化,可复用,可封装

“欠缺基本的代码层面的封装和隔离,代码层面没有组件化”

03—状态之间的互相依赖关系,只需声明即可

“UI之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到“Callback Hell”。”

02-4—组件化

image-20220807104559957.png 注意:左侧结构不是DOM树。DOM树不是js内部的一个变量,DOM本身是浏览器内部维护的一个东西,只能通过调用js DOM的API去修改DOM。DOM与实际看到的UI存在一一对应的关系。左侧的划分是自己写代码时的一个划分

组件化应该遵循的准则总结:

  • 组件是组件的组合/原子组件;
  • 组件内拥有状态,外部不可见;
  • 父组件可将状态传入组件内部。
状态归属问题

image-20220807105639305.png

【当前价格】属于Root节点

状态归属于两个节点向上寻找最近的祖宗节点。共享只能往上放。

【当前价格】如何改变?

将onChangeValue()向下传递。

思考:

1、React是单向数据流还是双向数据流?单向数据流。父组件给子组件传东西。

2、如何解决状态不合理上升的问题?第五节

3、组件的状态改变后,如何更新DOM?第四节

组件设计

1、组件声明了状态和UI的映射;输入几个状态,反馈UI

2、组件有Props/State两种状态;内部State,外部Props

3、“组件”可由其他组件拼接而成

组件代码会是什么样子?

1、组件内部拥有私有状态State

2、组件接受外部的Props状态提供复用性

3、根据当前的State/Props,返回一个UI

image-20220807162904399.png

生命周期

image-20220807162922993.png

挂载-状态改变-卸载三种状态

03—React(hooks)的写法

image-20220807162934038.png

用React封装好的函数更改状态才能做相应状态的刷新。setCount(count+1)

image-20220807162945708.png

Live Coding

Hook使用法则:不要在循环,条件或嵌套函数中调用Hook。

04—React的实现

04-1—问题

01—JSX不符合JS标准语法

image-20220807171924591.png

02—返回的JSX发生改变时,如何更新DOM

image-20220807163222300.png

指令式编程:手动告诉程序需要怎么做。

声明式编程:发出指令自动做完。

响应式编程:自己响应自己。

image-20220807163234340.png

虚拟DOM:更新状态—计算Diffing—Re-render

03—State/Props更新时,要重新触发render函数

04-2怎么去Diff?

image-20220807163250493.png

TrafeOff权衡

完美的最小Diff算法,需要O(n^3)的复杂度。

牺牲理论最小Diff,换取时间,得到了O(n)复杂度的算法:Heuristic(启发式的) O(n) Algorithm

image-20220807163446414.png

05—React的状态管理库

哪些东西适合放入状态管理库

准则:是否被整个app拥有的。e.g.当前用户的头像,每个组件都会使用

05-1—核心思想

image-20220807163502585.png

05-2—推荐

image-20220807163528213.png

05-3—状态机

image-20220807163553588.png

05-4—Modern.js/Reduck

image-20220807163633556.png

Live Coding

06—应用级框架科普

image-20220807163707343.png

image-20220807163716589.png

image-20220807163726019.png

image-20220807163737106.png