# React优化相关 ## 减少Render次数 - `PureComponent`: - 相当于一个`HOC`,将组件的`shouldComponentUpdate`覆盖 - 在`shouldComponentUpdate`中执行浅比较,**遍历第一层,使用`Object.is`比较值和引用地址** - 缺点: - 如果引用类型为多层,浅比较则失效 - 如果JSX中,往子组件传入的`props`为下文这样,会导致失效 ```js <Son value={value||[]}> // 每次渲染都是一个新的数组,引用地址改变 ``` - `React.memo`: - **仅**检查 `props` 变更 - 默认情况下其只会对复杂对象**做浅层对比**,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现 - 第二个参数参数为`(preProps,nextProps)`,返回值与`shouldComponentUpdate`**相反** - `Context`: - 当`value`值变化时会引发所有使用`Context`组件的更新 ## 减少渲染数量 - 懒加载:`React.lazy`等(常见于路由懒加载) - 虚拟列表 - 受控组件细化 - 受控组件通常会改变`state`属性,从而引发渲染,可将与受控组件相关的逻辑**单独摘出**,这样`state`更新只会引发部分渲染 - 独立数据请求 - 假设一个组件内部有**三个请求**,后续其中一个请求重新发起请求,就会导致组件重新渲染 - 如果把**三个请求独立成为三个组件**,这样就算重新请求也只会引发**局部重新渲染** - 手动批量更新 - `unstable_batchedUpdates`:`react-dom` 中提供了`unstable_batchedUpdates`方法进行手动批量更新 ```js const handerClick = () => { Promise.resolve().then(()=>{ unstable_batchedUpdates(()=>{ setB( { ...b } ) setC( c+1 ) setA( a+1 ) }) }) } // 三次更新合并为一次 ``` - 上文是因为在legacy模式下。将ReactDom.render改为createRoot也可解决上述问题 ## 减少渲染计算量 - `useMemo、useCallback`:防止内次渲染导致重新生成该变量 ## Diff方面 - 准确使用`key`:避免将key赋值为索引 - 减少跨层级操作:diff会将跨层级元素删除并重建 - 减少更改`type`或者`tagName`操作:type更改会导致该元素及其子元素节点被删除,并重新创建新节点
React优化相关
减少Render次数
PureComponent:相当于一个
HOC,将组件的shouldComponentUpdate覆盖在
shouldComponentUpdate中执行浅比较,遍历第一层,使用Object.is比较值和引用地址缺点:
如果引用类型为多层,浅比较则失效
如果JSX中,往子组件传入的
props为下文这样,会导致失效React.memo:props变更(preProps,nextProps),返回值与shouldComponentUpdate相反Context:value值变化时会引发所有使用Context组件的更新减少渲染数量
懒加载:
React.lazy等(常见于路由懒加载)虚拟列表
受控组件细化
state属性,从而引发渲染,可将与受控组件相关的逻辑单独摘出,这样state更新只会引发部分渲染独立数据请求
手动批量更新
unstable_batchedUpdates:react-dom中提供了unstable_batchedUpdates方法进行手动批量更新上文是因为在legacy模式下。将ReactDom.render改为createRoot也可解决上述问题
减少渲染计算量
useMemo、useCallback:防止内次渲染导致重新生成该变量Diff方面
key:避免将key赋值为索引type或者tagName操作:type更改会导致该元素及其子元素节点被删除,并重新创建新节点