浅谈useMemo与useCallback的区别与联系

useCallbackuseMemo 是 React 中用于性能优化的两个核心 Hook,它们的核心区别在于缓存的内容和使用场景:


​1. 核心区别​

​特性​ ​useCallback​ ​useMemo​
​缓存内容​ 缓存函数(函数引用) 缓存计算结果(值)
​语法​ useCallback(fn, deps) useMemo(() => value, deps)
​主要用途​ 避免子组件因父组件重新渲染而无效更新 避免重复计算昂贵的值

​2. 使用场景​

​useCallback​

  • ​传递回调函数给子组件​ ​:当子组件被 React.memo 包裹时,父组件传递的函数引用变化会导致子组件重新渲染。useCallback 可确保函数引用稳定。

    ini 复制代码
    const handleClick = useCallback(() => {
      // 逻辑
    }, [依赖项]);
    <ChildComponent onClick={handleClick} />
  • ​依赖项作为其他 Hook 的参数​ ​:例如 useEffect 或另一个 useCallback,需确保依赖函数稳定。

    scss 复制代码
    useEffect(() => {
      fetchData(handleSuccess); // handleSuccess 需稳定
    }, [handleSuccess]);

​useMemo​

  • ​复杂计算结果缓存​​:如大数据处理、格式转换等,避免每次渲染重复计算。

    ini 复制代码
    const filteredData = useMemo(() => {
      return data.filter(item => item.price > 100);
    }, [data]);
  • ​优化引用类型变量​​:如对象、数组,避免因引用变化触发子组件渲染。

    ini 复制代码
    const config = useMemo(() => ({ theme: "dark" }), []);

​3. 关键注意事项​

  • ​依赖数组​​:必须完整列出所有依赖项,否则可能导致闭包问题或无效缓存。

    scss 复制代码
    // 错误示例:依赖项缺失可能导致旧值引用
    const value = useMemo(() => data.value, []); // 应 [data]
  • ​避免滥用​​:过度使用会增加内存开销,仅对性能敏感场景使用。

  • ​与 React.memo 配合​ ​:useCallback 常与 React.memo 联用,优化组件渲染链。


​4. 性能对比示例​

​useCallback 场景​

ini 复制代码
// 父组件
const Parent = () => {
  const [count, setCount] = useState(0);
  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []); // 函数引用稳定

  return <Child onIncrement={increment} />;
};

// 子组件(React.memo)
const Child = React.memo(({ onIncrement }) => {
  // 仅在 onIncrement 变化时重新渲染
  return <button onClick={onIncrement}>+</button>;
});

​useMemo 场景​

javascript 复制代码
const ExpensiveComponent = ({ data }) => {
  const result = useMemo(() => {
    // 复杂计算(如排序、过滤)
    return data.sort((a, b) => a.value - b.value);
  }, [data]); // 数据变化时才重新计算

  return <div>{result}</div>;
};

​5. 总结​

  • ​useCallback​:缓存函数引用,优化子组件渲染。
  • ​useMemo​:缓存计算结果,避免重复计算。
  • ​共同原则​:仅在必要时使用,依赖数组需完整,避免内存泄漏。
相关推荐
attitude.x2 分钟前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java6 分钟前
CSS3核心技术
前端·css·css3
空山新雨(大队长)19 分钟前
HTML第八课:HTML4和HTML5的区别
前端·html·html5
猫头虎-前端技术1 小时前
浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
前端·css·node.js·bootstrap·ecmascript·css3·媒体
阿珊和她的猫1 小时前
探索 CSS 过渡:打造流畅网页交互体验
前端·css
元亓亓亓1 小时前
JavaWeb--day1--HTML&CSS
前端·css·html
β添砖java1 小时前
CSS的文本样式
前端·css
前端小趴菜051 小时前
css - 滤镜
前端·css
祈祷苍天赐我java之术1 小时前
理解 CSS 浮动技术
前端·css