useCallback 是 React 的性能优化 Hook,用于缓存函数引用,避免不必要的重新渲染。

useCallback Hook 详解

useCallback 是 React 的性能优化 Hook,用于缓存函数引用,避免不必要的重新渲染。

// 基本语法

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b] // 依赖项数组
);

示例 1: 基础用法对比

核心原理:

  • 父组件每次渲染,普通函数都会重新创建(新地址)
  • memo 子组件发现 onClick prop 变了(地址不同),就会重新渲染
  • useCallback 可以缓存函数,保持地址不变

父组件渲染次数: 1

0

❌ 没有 useCallback

0

✅ 使用 useCallback

观察结果: 点击“让父组件重新渲染”按钮后:
  • 左边红色数字会增加(每次都重新渲染)
  • 右边绿色数字保持为 1(只渲染一次)

示例 2: 依赖项的使用

计数: 0

依赖项规则:

  • 依赖项中包含函数内部使用的所有外部变量
  • 当依赖项变化时,函数会重新创建
  • 空数组 [] 表示函数永不重新创建

示例 3: 待办列表

学习 React Hooks
理解 useCallback
实践性能优化

关键点:

  • handleToggle 和 handleDelete 使用 useCallback 包裹
  • 使用函数式更新 setTodos(prev => ...) 避免依赖 todos
  • 子组件使用 memo 包裹,配合 useCallback 发挥作用

示例 4: 何时不需要 useCallback

0

❌ 不需要 useCallback 的情况:

  • 函数没有传递给子组件
  • 子组件没有使用 memo 包裹
  • 函数作为原生 DOM 元素的事件处理器
  • 使用了 React Compiler(自动优化)

✅ 需要 useCallback 的情况:

  • 函数作为 props 传递给 memo 包裹的子组件
  • 函数作为其他 Hook 的依赖项(如 useEffect)
  • 函数被用于复杂的计算或比较

总结:useCallback vs React Compiler

传统方式: 手动使用 useCallback 来优化性能

React 19 + Compiler: 编译器自动分析并添加必要的缓存

💡 建议: 在使用 React Compiler 的项目中, 优先让编译器处理优化。只在编译器无法覆盖的特殊场景下手动使用 useCallback。