Skip to content
字数
1042 字
阅读时间
5 分钟

useMemouseCallback 都是 React 中用于缓存计算结果的 Hooks,目的是减少不必要的重复计算或组件重渲染,提升性能。但它们的缓存对象使用场景有明确区别:

核心区别:缓存的对象不同

  • useMemo:缓存计算结果(值),比如复杂运算的返回值、对象、数组等。
  • useCallback:缓存函数本身,避免函数在每次渲染时被重新创建。

具体对比与场景

1. useMemo:缓存“值”,避免重复计算

当组件中存在耗时的计算逻辑(如大数据处理、复杂运算),或需要避免引用类型(对象/数组)被频繁创建导致子组件不必要重渲染时,使用 useMemo

语法

jsx
const memoizedValue = useMemo(() => {
  // 执行计算并返回结果(值)
  return 复杂计算的结果;
}, [依赖项数组]); // 依赖项变化时,重新计算并缓存新值

示例
假设有一个计算“数组元素总和”的耗时操作,且依赖于 list 变化:

jsx
function MyComponent({ list }) {
  // 用 useMemo 缓存计算结果,只有 list 变化时才重新计算
  const total = useMemo(() => {
    console.log('重新计算总和');
    return list.reduce((sum, item) => sum + item, 0);
  }, [list]); // 依赖 list

  return <div>总和:{total}</div>;
}
  • 如果不用 useMemo,每次组件渲染时都会执行 reduce 计算,即使 list 没变。
  • useMemo 后,只有 list 变化时才会重新计算,否则直接复用缓存的 total

2. useCallback:缓存“函数”,避免子组件无效重渲染

当需要将一个函数传递给子组件(尤其是使用 React.memo 优化的子组件)时,useCallback 可以缓存函数引用,避免因“函数每次渲染被重新创建”导致子组件不必要的重渲染。

语法

jsx
const memoizedCallback = useCallback(() => {
  // 函数逻辑
}, [依赖项数组]); // 依赖项变化时,重新创建函数并缓存

示例
子组件 ChildReact.memo 包裹(仅在 props 变化时重渲染),父组件传递一个回调函数:

jsx
// 子组件:用 React.memo 优化,避免无效重渲染
const Child = React.memo(({ onHandle }) => {
  console.log('子组件渲染了');
  return <button onClick={onHandle}>点击</button>;
});

// 父组件
function Parent() {
  const [count, setCount] = useState(0);

  // 用 useCallback 缓存函数,只有依赖变化时才重新创建
  const handleClick = useCallback(() => {
    console.log('点击事件');
  }, []); // 无依赖,函数始终是同一个引用

  return (
    <div>
      <p>计数:{count}</p>
      <button onClick={() => setCount(count + 1)}>加1</button>
      <Child onHandle={handleClick} />
    </div>
  );
}
  • 如果不用 useCallback,父组件每次渲染时,handleClick 都会被重新创建(函数引用变化),导致 Child 组件即使被 React.memo 包裹也会重新渲染。
  • useCallback 后,handleClick 引用不变(依赖为空数组),父组件渲染时 Child 不会因函数引用变化而重渲染。

关键总结

特性useMemouseCallback
缓存对象计算结果(值、对象、数组等)函数本身
本质useCallback(fn, deps) 等价于 useMemo(() => fn, deps)-
主要用途避免重复计算耗时操作避免子组件因函数引用变化而重渲染
依赖变化时重新计算并缓存新值重新创建函数并缓存新引用

注意事项

  • 不要过度使用:缓存本身有成本(内存占用),对于简单计算或不传递给子组件的函数,无需缓存。
  • 依赖项必须正确:如果依赖项变化但未加入依赖数组,会导致缓存的结果/函数过时,引发 bug。
  • useCallback 通常配合 React.memo 使用,否则意义不大(子组件本身会频繁重渲染时,缓存函数没用)。

贡献者

The avatar of contributor named as jiechen jiechen

页面历史

撰写