如何使用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,只在必要时使用(如性能敏感场景或子组件依赖函数引用时)。

相关推荐
用户797476112731 分钟前
Mysql RR事务隔离级别引发的生产Bug,你中招了吗?
前端
Mintopia3 分钟前
🧠 三分视界:Three.js 离屏渲染与多重视角的艺术
前端·javascript·计算机图形学
JarvanMo12 分钟前
Dart & Flutter DevTools 扩展
前端
yuko093114 分钟前
【手机验证码】手机号格式化光标异常问题
前端
原生高钙15 分钟前
高性能前端埋点上报系统的架构与实现
前端·面试
水痕0120 分钟前
nginx一个域名下部署多套前端项目
运维·前端·nginx
Anyin23 分钟前
Spring AI Alibaba - DeepResearch 前端主体 UI 构建
前端·ai编程·trae
非优秀程序员23 分钟前
8 个提升开发者效率的小众 AI 项目
前端·人工智能·后端
河畔一角31 分钟前
一些感悟
前端
excel37 分钟前
理解 JavaScript 中的 for...in 与 for...of 的区别
前端