1.关于React
React特点:声明式、组件化、跨平台
影响web性能的主要原因
等待资源加载时间和大部分情况下浏览器单线程执行是影响 web 性能的两大主要原因。
-
对于一次请求太多资源?网络请求慢?使用React.Lazy&React.Suspense
-
对于资源加载失败:使用ErrorBoundary
-
对于JS 执行、浏览器计算样式布局、UI 绘制
- 异步更新
- 时间切片
- React Fiber
react更新流程
-
Scheduler (调度器)
- 维护
时间切片(类似requestldleCallback) - 与浏览器任务调度
- 优先级调度
- 维护
-
Reconciler (协调器)
- 将JSX 转化为
Fiber - Fiber 树对比(双缓存)
- 确定本次更新的 Fiber
- 将JSX 转化为
-
Renderer (渲染器)
- 渲染器用于管理一棵
React 树 - 使其根据底层平台进行不同的调用。
- 渲染器用于管理一棵
React优缺点
-
优点
- 快速响应: Fiber
- 组件化:复用性强
- 声明式编程
- 跨平台: 只需修改渲染器【React-Native...】
-
缺点?
- 大型应用需要配套学习 状态管理、路由工具
- 不适合小型应用,需要用 babel 处理
2.React基础
- web应用&组件
组件
-
类式组件
- 继承+构造函数
- this
- 生命周期
- render方法
-
函数式组件
- 没有生命周期,借助hook
- return JSX
函数式组件相较于类式组件的优点:
- 没有复杂的生命周期
- 支持自定义 hook,逻辑复用方便
使用时:
- 将 UI 拆成多个独立单元,这些单元组合可以构成多种视图展示,这些独立单元就是组件。组件相当于原子。
- hook 贴近组件内部运行的各种概念逻辑,effect、state、context等。hooks 更贴切于电子。
问题:React怎么知道哪个state对应哪个 useState?
React 靠的是 Hook 调用的顺序,所以只能在最顶层使用 Hook。
错误写法
正确写法
Hook 规则 & 原理
- 在 React函数组件中 或自定义 Hook 中调用
- 自定义 Hook 必须以 use 开头
- Hook 中的 state 是完全隔离的
React解决过期闭包问题
在useEffect中设置依赖值,有变化就进行更新,解决过期闭包影响输出
3.场景案例
常见API及作用
常见Hook及作用
组件划分:layout
|page|component
组件间通信
父传子
- 知道子组件的表现,直接通过 props 传递即可
- 不知道具体子组件表现呢? 用props.children
写一个SizeWrapper组件,遍历子组件传递props,不用再分别在每一个子组件传递
子传父
子组件:将内容作为参数,放到父组件的回调函数中;在父组件:调用函数拿到结果值
此处用了ref的转发:在子组件给ref添加方法和参数,通过
forwardRef进行转发,父组件通过useRef取出,调用方法
组件间共享
- reducer&context
- react-redux
组件性能优化
三个组件:name counter calcvalue,只要有一个组件变化,整体全部重新渲染
优化1:用生命周期钩子比对
存在的问题:count可以直接比较,但是函数的比较一定是真,因为没有两个完全相等的函数,依旧会重新渲染
优化1.1:使用useCallback便可以解决
优化2:使用useMemo解决会重新计算函数值的情况
组件挂载位置
实现:组件写在蓝色容器,实际挂载在黄色容器【相当于在一个组件内写了抽屉,另一个兄弟组件也能用】
使用reactPortal实现
冒泡问题:触发hide后会冒泡再自动触发show
那么使用reactPortal后会冒泡至哪里?
一个从 poral 内部触发的事件会一直冒泡至包含 React 树的祖先,即便这些元素并不是DOM树 中的祖先。所以会冒泡到蓝色盒子。
逻辑复用
实现基础请求、轮询请求、取消请求、更改轮询请求时间间隔
步骤:
- 设置hook的入参
- 设置要用到的状态
- 需调用的方法
- 可变的时间、请求参数