标准答案

  1. useMemo 缓存一个计算结果,依赖不变时返回上一次结果。
  2. useCallback 缓存一个函数引用,本质上常可理解为 useMemo 返回函数。
  3. 它们适合昂贵计算、传给 memo 子组件的稳定 props、作为 effect 依赖的稳定函数等场景。
  4. 简单计算或普通内联函数不一定需要缓存,盲目使用会让代码更复杂。
  5. 性能优化应先定位瓶颈,再用 memo、useMemo、useCallback、拆分组件或调整状态位置解决。

题目解析

这道题要避免回答成“useMemo 优化值,useCallback 优化函数”就结束。

缓存也有成本。React 需要保存上一次值和依赖,并比较依赖是否变化。

如果子组件没有 React.memo,父组件传入稳定函数引用也不一定减少子组件渲染。

代码示例

下面的 useMemo 适合缓存较重的过滤计算,useCallback 用来给 memo 子组件稳定回调引用。

TSX
const visibleUsers = useMemo(() => {
  return users.filter(user => user.name.includes(keyword))
}, [users, keyword])

const handleSelect = useCallback((id: string) => {
  setSelectedId(id)
}, [])

return <UserList users={visibleUsers} onSelect={handleSelect} />

常见误区

  • 所有函数都包 useCallback,所有计算都包 useMemo,代码变复杂但没有性能收益。
  • 依赖数组写错,缓存了错误结果或读到旧变量。
  • 以为 useCallback 能阻止当前组件重新渲染,它只能稳定函数引用。

作者信息