当前位置: 首页 > news >正文

在 React 中,什么情况下需要用 useCallback 和 useMemo?它们的区别是什么?

一、先理解核心问题

React 组件为什么会重复渲染?

因为:

父组件重新执行 → 子组件默认重新执行

哪怕 props 没变。

而且:

  • 每次 render 都会重新创建函数

  • 每次 render 都会重新创建对象

  • 每次 render 都会重新执行计算

这就可能导致:

  • 子组件无意义重新渲染

  • 复杂计算重复执行

  • 性能浪费

于是有了:

useCallback → 缓存函数 useMemo → 缓存计算结果

二、useCallback 是什么?

缓存“函数引用”

场景:避免子组件重复渲染

看例子:

function Parent() { const [count, setCount] = useState(0) const handleClick = () => { console.log("clicked") } return <Child onClick={handleClick} /> }

问题:

每次 Parent render:

handleClick = new Function()

即使逻辑没变,函数地址变了。

如果子组件是:

const Child = React.memo(({ onClick }) => { console.log("child render") return <button onClick={onClick}>Click</button> })

它仍然会重新渲染,因为:

旧函数 !== 新函数

用 useCallback

const handleClick = useCallback(() => { console.log("clicked") }, [])

现在函数引用不会变。

子组件不会重复 render。


三、useMemo 是什么?

缓存“计算结果”

场景:复杂计算避免重复执行

function App({ list }) { const sortedList = list.sort() // 每次 render 都执行 return <div>{sortedList.length}</div> }

如果 list 很大,每次都排序很浪费。


用 useMemo

const sortedList = useMemo(() => { return list.sort() }, [list])

只有 list 变了才重新计算。


四、核心区别

useCallbackuseMemo
缓存什么函数计算结果
返回值函数任意值
本质useMemo 的语法糖底层实现

实际上:

useCallback(fn, deps)

等价于:

useMemo(() => fn, deps)

五、什么时候需要 useCallback?

✅ 1. 传给 React.memo 子组件的函数

<Child onClick={handleClick} />

子组件用 React.memo 包裹时。


✅ 2. 传给 useEffect 依赖数组

useEffect(() => { doSomething() }, [handleClick])

如果 handleClick 每次变,effect 每次触发。


✅ 3. 大量列表中的事件函数

例如 1000 行表格,每行一个按钮。


六、什么时候需要 useMemo?

✅ 1. 复杂计算

  • 排序

  • 过滤

  • 映射

  • 数据处理


✅ 2. 生成大对象

const config = useMemo(() => ({ headers: {...}, timeout: 5000 }), [])

避免对象引用变化导致子组件刷新。


✅ 3. 防止依赖变化

例如:

useEffect(() => { ... }, [config])

如果 config 是新对象,每次都触发。


七、什么时候不要用(非常重要)

很多人滥用。

❌ 1. 简单函数不需要

const add = () => a + b

没必要缓存。


❌ 2. 组件不使用 React.memo

如果子组件本身每次都会渲染,useCallback 没意义。


❌ 3. 计算很轻量

简单 map 不需要 useMemo。


八、性能误区

⚠ useCallback / useMemo 不是性能优化万能钥匙。

它们:

  • 也有性能成本

  • 也要比较依赖

  • 也会增加复杂度

React 官方建议:

先写清晰代码
真有性能问题再优化


九、实际开发经验(你这个水平该知道)

真正有用场景:

  • 大型表格

  • 数据平台

  • 编辑器

  • 可视化平台

  • 高频状态更新

基础业务系统:

基本用不到。


十、面试标准回答

可以这样说:

useCallback 用于缓存函数引用,主要用于避免因为函数重新创建导致的子组件不必要渲染,通常配合 React.memo 使用。

useMemo 用于缓存计算结果,避免复杂计算在每次渲染时重复执行。

两者本质上 useCallback 是 useMemo 的语法糖。

它们属于性能优化手段,不应该滥用,只有在存在性能瓶颈或引用稳定性需求时才使用。


十一、再给你进阶一点

React 18 之后:

  • 大多数小组件没必要手动优化

  • React Compiler 未来会自动优化

  • 过度 useCallback 反而降低可读性


一句话总结

useCallback → 缓存函数 useMemo → 缓存值 核心目的 → 控制引用稳定 + 避免重复计算

http://www.jsqmd.com/news/437017/

相关文章:

  • 3月4日(121-123题)
  • 十二层PCB选型指南:2026高速电路板厂商排名
  • PCB四层板哪家好?5大厂商综合评测排名
  • 无线数采网关有哪些功能特点
  • 某能源企业AI转型:提示工程架构师介入后,设备故障率降18%
  • 风机润滑数据采集物联网解决方案
  • 2026最新 | 3款离线免费pdf转word工具软件推荐,教你选对不踩坑
  • 云原生网关 Ingress-Nginx 链路追踪实战:OpenTelemetry 采集与观测云集成方案
  • ElasticSearch核心原理详解
  • 基于 YOLO26 的电瓶车自行车智能检测(中英文双版) | 附完整源码与效果演示
  • XTDrone平台下创建自己的world文件并运行
  • 基于YOLO26的5类常见水果检测系统(中英文双版) | 附完整源码与效果演示
  • 高量程电导率TDS盐度测定仪
  • 模块化与组件化:90%的前端开发者都没搞懂的本质区别
  • 人工智能之数字生命-本能动作体系规范(任务/方法/本能方法函数)
  • 书匠策AI:解锁课程论文高效写作的“智慧密钥”
  • 工业防爆小型气象站
  • [特殊字符]书匠策AI:解锁课程论文新境界,让学术写作如行云流水![特殊字符]
  • 自然语言处理 —— 语言资源
  • 智能考试系统核心模块回归测试:从基础数据到业务闭环的深度验证
  • 逻辑回归实战:从原理到不平衡数据优化(含欠拟合/过拟合诊断与召回率提升) - 教程
  • 自然语言处理 —— 简介
  • 止痒去屑洗发水怎么选?2026年热门品牌大盘点,去油去屑洗发水/去屑洗发水/止痒去屑洗发水,止痒去屑洗发水产品排行榜单 - 品牌推荐师
  • 书匠策AI:解锁课程论文新姿势,让学术创作如虎添翼!
  • 用Matlab实现基于LBP的面部表情识别
  • [特殊字符]解锁课程论文新姿势!书匠策AI:你的学术超能力启动站[特殊字符]
  • 全球前11%:奋飞咨询助力金属贸易企业实现Ecovadis评分19分跃升 - 奋飞咨询ecovadis
  • 爱喝咖啡的小姐姐订单发货说明
  • pikachu靶场——Cross-Site Scripting-6 XSS之href和js(Kali系统)
  • HGVE-2023-E006(CVE-2023-5870)