React 中的 useCallback 入门指南:是真需要,还是假怪?

在学习 React 时,很多人初步接触 useCallback 都有一个同样的疑问:

"useCallback 到底是干啥的?不是简单地就是'缓存一个函数'吗?我一直不明白它真正有什么用。"

这篇文章就来给你一个全方位、实操、有例实的 useCallback 入门指南,帮你真正理解它的作用。


1. useCallback 是什么?

它是 React 的一个 Hook,用来 缓存一个函数的引用,避免在组件重新渲染时重新创建该函数

基本用法:

复制代码
const memoizedCallback = useCallback(() => {
  // ...
}, [deps]);

当 deps 不变化时,这个函数就不会重新创建。


2. 为什么需要 useCallback?

React 组件每次重新渲染,所有的函数都是重新创建的。如果这个函数传给了子组件,那子组件就会被认为改变了 props,不论其内部是否真正改变。

如果子组件是 React.memo() 缓存的,那么这个 props 函数的变化就会打破缓存,导致子组件重新渲染。

useCallback 的作用,就是保证函数引用 在 deps 不变化时不变,从而避免子组件无效重渲染。


3. 简单示例

复制代码
const Child = React.memo(({ onClick }: { onClick: () => void }) => {
  console.log('Child 渲染了');
  return <button onClick={onClick}>子按钮</button>;
});

function Parent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log('Child 被点击');
  }, []);

  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>增加计数</button>
      <Child onClick={handleClick} />
    </div>
  );
}

每次点击"增加计数"按钮,如果你用了 useCallbackChild 就不会重渲染。


4. TypeScript 下不加参数类型会有问题?

是的,当 TypeScript 打开 strict mode 时,如果 useCallback 的函数有参数却没有指定类型,就会报错。

复制代码
const handleClick = useCallback((e) => {
  console.log(e.target);
}, []); // 报错:参数 'e' 类型不明

正确写法:

复制代码
const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
  console.log(e.target);
}, []);

为什么会报错?因为 TypeScript 对不包含参数类型的函数无法精确推断类型,尤其是返回值是 void 时更是如此。


5. 什么时候需要用 useCallback?

适合场景:

  • 函数被传给子组件

  • 子组件用了 React.memo()

  • 子组件性能故事明显

不需要的场景:

  • 函数只在本地使用

  • 没有性能问题,例如组件很小或非常简单


6. 小结

useCallback 不是所有场景都需要用,但在需要性能优化时,它是非常有用的工具。它和 React.memo 结合,就像 React 性能优化的黄金伴侣,用好了可以效果显著;用错了反而可能使性能下降。

最好的做法是:需时之用,而不是一上来就翘翘地拿一堆 useCallback

相关推荐
哈__6 分钟前
从入门小白到精通,玩转 React Native 鸿蒙跨平台开发:TouchableOpacity 触摸反馈组件
react native·react.js·harmonyos
古茗前端团队20 分钟前
视频播放弱网提示实现
react.js
哈__31 分钟前
入门小白到精通,玩转 React Native 鸿蒙跨平台开发:Button 按钮组件与点击事件
react native·react.js·harmonyos
哈__32 分钟前
React Native 鸿蒙开发:内置 Share 模块实现无配置社交分享
javascript·react native·react.js
怕浪猫2 小时前
React从入门到出门 第五章 React Router 配置与原理初探
前端·javascript·react.js
哈__2 小时前
React Native 鸿蒙跨平台开发:LayoutAnimation 实现鸿蒙端表单元素的动态添加动画
react native·react.js·harmonyos
哈__2 小时前
React Native 鸿蒙跨平台开发:Vibration 实现鸿蒙端设备的震动反馈
javascript·react native·react.js
哈__2 小时前
React Native 鸿蒙跨平台开发:LayoutAnimation 实现鸿蒙端页面切换的淡入淡出过渡动画
javascript·react native·react.js
哈__2 小时前
React Native 鸿蒙跨平台开发:Animated 实现鸿蒙端组件的上下滑动入场动画
react native·react.js·harmonyos
UIUV16 小时前
模块化CSS学习笔记:从作用域问题到实战解决方案
前端·javascript·react.js