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

相关推荐
lbb 小魔仙6 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js
早點睡39011 小时前
高级进阶 ReactNative for Harmony 项目鸿蒙化三方库集成实战:react-native-drag-sort
react native·react.js·harmonyos
C澒11 小时前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
发现一只大呆瓜12 小时前
虚拟列表:从定高到动态高度的 Vue 3 & React 满分实现
前端·vue.js·react.js
全栈探索者13 小时前
列表渲染不用 map,用 ForEach!—— React 开发者的鸿蒙入门指南(第 4 期)
react.js·harmonyos·arkts·foreach·列表渲染
程序员Agions14 小时前
useMemo、useCallback、React.memo,可能真的要删了
前端·react.js
NEXT0615 小时前
React Hooks 进阶:useState与useEffect的深度理解
前端·javascript·react.js
早點睡39016 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-flash-message 消息提示三方库适配
react native·react.js·harmonyos
早點睡39017 小时前
高级进阶 ReactNative for Harmony项目鸿蒙化三方库集成实战:react-native-image-picker(打开手机相册)
react native·react.js·harmonyos
早點睡39017 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-easy-toast三方库适配
react native·react.js·harmonyos