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

93 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第9天

PPT: bytedance.feishu.cn/file/boxcnS…

前置知识

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

01 React 的历史与应用

应用

  1. 前端应用开发
  2. 移动原生应用开发
  3. 结合Electron, 进行桌面应用开发

历史

2010年 Facebook在其php生态中, 引入了xhp框架, 首次引入了组合式组件的思想, 启发了后来的React的设计

2011年 Jordan Walke创造了FaxJS, 也就是后来的React原型

2012年 在Facebook收购Instagram后, 该FaxJS项目在内部得到使用, Jordan Walke基于FaxJS的经验, 创造了React

2013年 React正式开源

02 React 的设计思路

UI编程痛点

  1. 状态更新, UI不会自动更新, 需要手动地调用DOM进行更新
  2. 欠缺基本的代码层面的封装和隔离, 代码层面没有组件化
  3. UI之间的数据依赖关系, 需要收到维护, 如果依赖链路长, 则会遇到"Callback Hell"

转化式系统与转换式

转换式系统

  • 给定[输入]求解[输出]

响应式系统

  • 监听事件
  • 消息驱动
  • 事件 -> 执行既定的回调 -> 状态变更

前端

  • 事件 -> 执行既定的回调 -> 状态变更 -> UI更新
  1. 状态更新, UI自动更新
  2. 前端代码组件化, 可复用, 可封装
  3. 状态之间的互相依赖关系, 只需声明即可

组件化

  1. 组件是组件的组合或原子组件
  2. 组件内拥有状态, 外部不可见
  3. 父组件可将状态传入组件内部

思考

  1. React 是单向数据流, 还是双向数据流?

    单向, 永远都是父组件向子组件传递数据. 但这不代表子组件不能改变父组件状态, 父组件可以通过传递函数给子组件, 实现子组件改变父组件状态

  2. 如何解决状态不合理上升的问题?

    可以通过状态管理库解决 见05 React状态管理库

  3. 组件的状态改变后, 如何更新DOM?

    见04 React的实现

组件设计

  1. 组件声明了状态和UI的映射
  2. 组件有Props/State两种状态
  3. "组件可由其他组件拼接而成"

思路

  1. 组件内部拥有私有状态State
  2. 组件接受外部的Props状态提供复用性
  3. 根据当前的State/Props, 返回一个UI

生命周期

Mounting 挂载

Updating 更新

Unmounting 卸载

03 React (hooks)的写法

useState

useEffect

⭐不要在循环, 条件或嵌套函数中调用hook

04 React 的实现

问题

  1. JSX不符合JS标准语法

    转义

  2. 返回的JSX发生改变时, 如何更新DOM

    通过Virtual DOM (虚拟DOM)

    是一种用于和真实DOM同步, 而在JS内存中维护的一个对象, 它具有和DOM类似的树状结构, 并和DOM可以建立一一对应的关系

    Change of State => Diffing => Re-render Virtual DOM

  3. State/Props更新时, 要重新触发render函数

How to Diff? (更新次数少 TradeOff 计算速度快)

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

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

Heuristic: 启发式的. (不一定对, 感觉上是对的)

  • 不同类型的元素: 替换
  • 同类型的DOM元素 更新
  • 同类型的组件元素 递归

弊病: 当一个父组件状态改变, 所有子节点会递归render, 影响性能

05 React 状态管理库

核心思想: 将状态抽离到UI外部进行统一管理 ⭐

缺点: 降低组件的复用性, 增加耦合

因此组件库是不会用状态管理库, 一般业务代码才会用

一些状态管理库: redux, xstate, mobx, recoil

状态机: 当前状态, 收到外部事件, 迁移到下一个状态

06 应用级框架科普

  1. NEXT.js
  2. MODERN.js
  3. Blitz

课后思考

1 React组件的render函数, 在哪些时机下, 会被重新执行?

2 React这种函数式编程, 和vue这种基于模板语法的前端框架, 各有什么优点和缺点?

3 React推荐使用组合来进行组件的复用, 而不是继承, 背后有什么样的考虑