如何在 React 中正确地使用 useCallback 避免不必要的子组件重新渲染?

如何在 React 中正确地使用 useCallback 避免不必要的子组件重新渲染?

在 React 中,useCallback 用于缓存函数实例,防止因父组件重新渲染导致传递给子组件的函数引用变化,从而避免子组件不必要的重新渲染(尤其是配合 React.memo 使用时)。

正确用法示例:

import React, { useState, useCallback } from 'react';

const Child = React.memo(({ onIncrement }) => {
  console.log('Child rendered');
  return <button onClick={onIncrement}>+</button>;
});

const Parent = () => {
  const [count, setCount] = useState(0);
  const [theme, setTheme] = useState('light');

  // 使用 useCallback 缓存函数,仅当 count 变化时才更新函数引用
  const handleIncrement = useCallback(() => {
    setCount(c => c + 1);
  }, []); // 依赖项为空数组,函数实例在组件整个生命周期中保持不变

  return (
    <div>
      <p>Count: {count}</p>
      <p>Theme: {theme}</p>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
      <Child onIncrement={handleIncrement} />
    </div>
  );
};

解析:

  • 若不使用 useCallback,每次 Parent 重新渲染(如切换 theme)都会创建一个新的 onIncrement 函数,导致 Child 即使使用 React.memo 也会重新渲染。
  • 使用 useCallback 并传入适当的依赖数组(此处无外部依赖,故为 []),可确保函数引用稳定。
  • 注意:useCallback 不是性能优化的“银弹”,仅在配合 React.memo 或作为依赖传给 useEffect/useMemo 等 hook 时才有意义。滥用反而增加计算开销。

关键点: useCallback 的核心作用是保持函数引用的稳定性,而非提升函数执行性能。

发表评论 (审核通过后显示评论):

昵称:
邮箱:
内容: