React基础与实践|青训营笔记

121 阅读3分钟

1.关于React

React特点:声明式、组件化、跨平台

影响web性能的主要原因

等待资源加载时间和大部分情况下浏览器单线程执行是影响 web 性能的两大主要原因。

  • 对于一次请求太多资源?网络请求慢?
    • 使用React.Lazy&React.Suspense

702fd547f75cb8518205fbea35e147f.png

  • 对于资源加载失败?
    • 使用ErrorBoundary

f3f8d6bd21d3e209b9f787cd45ae8e6.png

  • 对于JS 执行、浏览器计算样式布局、UI 绘制
    • 异步更新
    • 时间切片
    • React Fiber

react更新流程

  • Scheduler (调度器)
    • 维护时间切片 (类似requestldleCallback)
    • 与浏览器任务调度
    • 优先级调度
  • Reconciler (协调器)
    • 将JSX 转化为 Fiber
    • Fiber 树对比(双缓存)
    • 确定本次更新的 Fiber
  • Renderer (渲染器)
    • 渲染器用于管理一棵 React 树
    • 使其根据底层平台进行不同的调用。

669e386c804495f8943d3c8140e03d8.png

b3b3afbd86144d961778f22a4b24fc8.png

React优缺点

  • 优点
    • 快速响应: Fiber
    • 组件化:复用性强
    • 声明式编程
    • 跨平台: 只需修改渲染器【React-Native...】
  • 缺点?
    • 大型应用需要配套学习 状态管理、路由工具
    • 不适合小型应用,需要用 babel 处理

2.react基础

web应用&组件

c6aec36e734ad289aab215ce87bec6e.png

组件

f0ad3c83bfbc80f1cc358e2db06bcbf.png

  • 类式组件
    • 继承+构造函数
    • this
    • 生命周期
    • render方法
  • 函数式组件
    • 没有生命周期,借助hook
    • return JSX

函数式组件相较于类式组件的优点:

  • 没有复杂的生命周期
  • 支持自定义 hook,逻辑复用方便

使用时:

  1. 将 UI 拆成多个独立单元,这些单元组合可以构成多种视图展示,这些独立单元就是组件。组件相当于原子。
  2. hook 贴近组件内部运行的各种概念逻辑,effect、state、context等。hooks 更贴切于电子。

问题:React怎么知道哪个state对应哪个 useState?

React 靠的是 Hook 调用的顺序,所以只能在最顶层使用 Hook

错误写法

2fb43cd50df93950d2dad24eb15d9c0.png

正确写法

fd34b6561410e52ce3496cab68d9b55.png

Hook 规则 & 原理

  • 在 React函数组件中 或自定义 Hook 中调用
  • 自定义 Hook 必须以 use 开头
  • Hook 中的 state 是完全隔离的

React解决过期闭包问题

6624e05dd83c43a193fba975dfc6592.png 在useEffect中设置依赖值,有变化就进行更新,解决过期闭包影响输出

3.场景案例

常见API及作用

dcb2e139fe4c9a4f78dc1c4774b343b.png

常见Hook及作用

dc5770e057c8d6497635a083a528843.png

组件划分:layout | page | component

组件间通信

父传子

  • 知道子组件的表现,直接通过 props 传递即可
  • 不知道具体子组件表现呢? 用props.children

ba3db6b447793f9c2049d1bd4b7151a.png 写一个SizeWrapper组件,遍历子组件传递props,不用再分别在每一个子组件传递

子传父

子组件:将内容作为参数,放到父组件的回调函数中;在父组件:调用函数拿到结果值 b4c1c7437572df800cc3a8e30746330.png 此处用了ref的转发:在子组件给ref添加方法和参数,通过forwardRef进行转发,父组件通过useRef取出,调用方法

组件间共享

  • reducer&context 31551e450538d9eb0b0a3913d100db2.png

fe975122223551855b27341353d9f6e.png

  • react-redux

0dbdf2c0381a546187ccc0ccfc55d46.png

90a62055e3ec3118d33ae8fc25a6d9a.png

组件性能优化

三个组件:name counter calcvalue,只要有一个组件变化,整体全部重新渲染

27564bfeced48233beab367db6d6c8a.png

优化1:用生命周期钩子比对

26b6a23b46b8c77fd7e803c0abd47fc.png 存在的问题:count可以直接比较,但是函数的比较一定是真,因为没有两个完全相等的函数,依旧会重新渲染

优化1.1:使用useCallback便可以解决

eef5a7c97ad4b9f1fe38140a24da327.png

优化2:使用useMemo解决会重新计算函数值的情况

1dd4ec5b262655e086241086b99d6e8.png

组件挂载位置

实现:组件写在蓝色容器,实际挂载在黄色容器【相当于在一个组件内写了抽屉,另一个兄弟组件也能用】

31a29969aaed7e5c843d590c3f41e5e.png

使用reactPortal实现

bc0f7c7210c32f62a27402e843951ba.png

冒泡问题:触发hide后会冒泡再自动触发show

8e90a4605b9cbb678f60ec23a980679.png

那么使用reactPortal后会冒泡至哪里?

1193fff86aa1feb6a68bf92db034d19.png

一个从 poral 内部触发的事件会一直冒泡至包含 React 树的祖先,即便这些元素并不是 DOM树 中的祖先。所以会冒泡到蓝色盒子。

逻辑复用

实现基础请求、轮询请求、取消请求、更改轮询请求时间间隔

27a144110b48d5f274a7a4b93c12dd7.png

步骤:

  • 设置hook的入参
  • 设置要用到的状态
  • 需调用的方法
  • 可变的时间、请求参数 203fce58b6d75eac56de71283cdcb62.png

0ae274dfffe5942b7fc1ab10cf6d629.png