React 词条目录
前端Wiki/词条/useMemo 与 useCallback

useMemo 与 useCallback

定义两个性能优化 Hook:缓存计算结果(useMemo)与缓存函数引用(useCallback)

React 重渲染的逻辑是「父组件渲染,子组件无条件跟着渲染」。useMemo/useMemo 的作用是缓存:useMemo(() => heavyCalc(a, b), [a, b]) 依赖不变时返回缓存结果避免重算;useCallback(fn, [deps]) 依赖不变时返回同一个函数引用,避免子组件因新函数 prop 而无效重渲染。

正确用法:先测后优化(React DevTools Profiler 找真实瓶颈);昂贵计算配 useMemo;子组件被 memo 包裹且传入函数 prop 时配 useCallback——缓存与 memo 配套才有意义。滥用反而更慢:缓存本身要比较依赖、占用内存,简单场景下缓存成本比重算还高。

HTML
const { useMemo, useCallback, memo, useState, useEffect } = React;

// 子组件被 memo 包裹:props 不变则不重渲染
const Item = memo(function Item({ onClick, label }) {
  console.log('Item 渲染');   // 父无脑渲染时这里也会刷
  return <button onClick={onClick}>{label}</button>;
});

function List() {
  const [q, setQ] = useState('');
  const [n, setN] = useState(0);

  // 昂贵计算:q 不变就不重算
  const filtered = useMemo(() => hugeFilter(q), [q]);

  // 函数引用稳定:Item 的 props 不变 → 不重渲染
  const del = useCallback(id => remove(id), []);

  return (
    <div>
      <input value={q} onChange={e => setQ(e.target.value)} />
      <button onClick={() => setN(n + 1)}>n={n}</button>
      {filtered.map(x => <Item key={x.id} onClick={del} label={x.t} />)}
    </div>
  );
}
⚠ 常见误区
🔗 相关词条HooksuseEffect 副作用Context 跨层通信
← 返回来源章节useMemo 与 useCallback