浅谈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​:缓存计算结果,避免重复计算。
  • ​共同原则​:仅在必要时使用,依赖数组需完整,避免内存泄漏。
相关推荐
之歆7 分钟前
Day07_CSS盒子模型 · 样式继承 · 用户代理样式
前端·css
DanCheOo23 分钟前
AI 应用的安全架构:Prompt 注入、数据泄露、权限边界
前端·人工智能·prompt·安全架构
We་ct1 小时前
深度剖析浏览器跨域问题
开发语言·前端·浏览器·跨域·cors·同源·浏览器跨域
weixin_427771612 小时前
前端调试隐藏元素
前端
爱上好庆祝3 小时前
学习js的第五天
前端·css·学习·html·css3·js
C澒3 小时前
IntelliPro 产研协作平台:基于 AI Agent 的低代码智能化配置方案设计与实现
前端·低代码·ai编程
一袋米扛几楼983 小时前
【Git】规范化协作:详解 GitHub 工作流中的 Issue、Branch 与 Pull Request 最佳实践
前端·git·github·issue
网络点点滴3 小时前
前端与后端的区别与联系
前端
EnCi Zheng4 小时前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen4 小时前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控