React Hook中的性能优化:memo、useCallback、useMemo
一、概念
React 性能优化的起因:
在React中,默认情况下,当父组件重渲染时,子组件也会重渲染。
在React中,子组件默认随父组件更新而更新。
React 性能优化的方向:通过缓存,减少渲染次数、减少重复计算。
React Hook性能优化的总结:memo缓存组件、useCallback缓存函数、useMemo缓存计算结果。
二、memo:使用React.memo高阶组件包裹子组件,当props不变时该子组件不会重新渲染。
import { memo } from "react";
function Child() {
return <div>{Math.random()}</div>;
}
export default memo(Child);
默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现:
function MyComponent(props) {
/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
/*
如果把 nextProps 传入 render 方法的返回结果与
将 prevProps 传入 render 方法的返回结果一致则返回 true,
否则返回 false
*/
}
export default React.memo(MyComponent, areEqual);
三、useCallback:memo无法判断props中的函数是否改变。把回调函数和依赖项数组传入useCallback,返回该回调函数的memoized版本,当依赖项不变时该回调函数不会更新。
useCallback 要和 shouldComponentUpdate或React.memo 配套使用
子组件如果不用shouldComponentUpdate或React.memo,父组件更新时一定会更新
一般项目无需考虑性能优化,也就无需使用 useCallback,除非有个别非常复杂的组件,单独使用即可
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)
应用于父组件把函数通过props传入子组件的场景。
当点击button1,Child重渲染;点击button2,Child没有重渲染。
import "./styles.css";
import { useCallback, useState, memo } from "react";
import Child from "./child";
export default function App() {
const [count, setCount] = useState(false);
const [count2, setCount2] = useState(false);
const onClickChild = useCallback(() => {}, [count]);
return (
<div className="App">
<Child onClick={onClickChild}></Child>
<button
onClick={() => {
setCount(!count);
}}
>
count:{count.toString()}
</button>
<button
onClick={() => {
setCount2(!count2);
}}
>
count2:{count2.toString()}
</button>
</div>
);
}
四、useMemo:把回调函数和依赖项数组传入useMemo,返回该回调函数返回值的memoized版本,当依赖项不变时该返回值不会重新计算。
应用于需要避免多次渲染时的重复计算的场景。
当a和b不变时,computeExpensiveValue(a, b)的返回值不会重新计算。
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

浙公网安备 33010602011771号