如何使用useCallback优化React性能?

JS 基础知识回顾

Javascript中,函数是一种引用类型的变量,即存放的并非真实的值,而是引用值,类似于C语言中的指针类型。

当我们在JavaScript中, 每次定义函数(如 () => {}function() {})时,都会在内存中创建一个新的对象。例如:

Javascript 复制代码
const a = () => {};
const b = () => {};
console.log(a === b); // false(两个不同的函数对象)
  • 关键点 : 函数a和函数b的内容虽然完全相同,但是它们各自创建,代表着内存中的不同位置
  • 结果 : 函数a和函数b实际的值(类似于指针)不一样,因此将它们两相比较的结果就是false

React中函数引用的频繁变化

React中,函数式组件本身就是一个 JavaScript 函数,每次重新渲染时,整个函数体会从头到尾执行一次,包括内部的所有变量和函数声明,组件内部定义的函数会被重新创建,使用新的内存地址。

当父组件将函数通过 props 传递给子组件时,即使函数内容未变,子组件也会因 props 的引用不同而触发重新渲染。

例如,当我们在组件内部定义一个函数时(以 handleClick为例),它本质上是这样工作的:

JSX 复制代码
const Parent = () => {
  // 每次 Parent 渲染时,都会重新声明并创建一个新的 handleClick 函数
  const handleClick = () => {
    console.log("Click");
  };

  return <Child onClick={handleClick} />;
};
  • 关键点:函数组件本身是一个 JavaScript 函数,每次重新渲染时,整个函数体会从头到尾执行一次,包括内部的所有变量和函数声明。
  • 结果handleClick 会被重新创建为一个新的函数对象(新的内存地址),即使函数内容没有变化。不仅如此,每当父组件重新渲染时,Child 就会重新渲染,因为 onClick 的引用变了。

如何解决?用useCallback缓存函数

如果有一种方法,能通过缓存函数,仅在某些条件下(比如依赖项变化时)才生成新函数 ,否则复用上一次的函数引用,那么就可以避免重复创建相同内容的函数引用 。可惜,这只是在白日做梦o (T ヘ To)

事实上,React 中的useCallback钩子就可以帮助我们实现刚才的想法。 通过 useCallback 缓存函数,可以避免每次渲染时重新创建函数:

JSX 复制代码
const Parent = () => {
  // ✅ 用 useCallback 缓存函数,依赖项为空数组(函数只创建一次)
  const handleClick = useCallback(() => {
    console.log("Click");
  }, []);

  return <Child onClick={handleClick} />;
};
  • 关键点handleClick 的引用保持不变,子组件 Childprops 不会发生变化。
  • 结果 :父组件更新 count 时,Child 不会因 onClick 引用变化而重新渲染,从而解决函数引用频繁变化带来的性能问题。

总结

  • 根本问题:函数组件每次渲染时都会重新执行,导致内部函数重新声明。
  • 关键影响:函数引用变化会触发子组件不必要的渲染(即使内容相同)。
  • 解决方案 :用 useCallback 缓存函数,仅在依赖项变化时重新创建函数。

在实际使用时,我们需要清楚何时需要优化函数引用,何时可以直接定义函数。

注意,不要滥用 useCallback,只在必要时使用(如性能敏感场景或子组件依赖函数引用时)。

相关推荐
恋猫de小郭15 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端