【React的useMemo钩子详解】

React 的 useMemo 钩子详解

useMemo 是 React 提供的一个性能优化 Hook,用于缓存计算结果,避免在每次渲染时都进行重复计算。

基本语法

javascript 复制代码
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 第一个参数:计算函数,返回需要缓存的值
  • 第二个参数:依赖项数组,当依赖项变化时才会重新计算

核心机制

  1. 缓存触发条件

    • 使用 Object.is 逐个比较依赖项
    • 任一依赖项变化 → 重新计算并缓存新值
    • 所有依赖项不变 → 直接返回缓存值
  2. 缓存存储方式

    • 存储在组件对应的 Fiber 节点
    • 组件卸载时缓存销毁
    • 空依赖数组 [] → 永久缓存

主要应用场景

1. 高性能计算优化

javascript 复制代码
const filteredList = useMemo(() => 
  hugeList.filter(item => item.value > threshold), 
[threshold, hugeList]);

2. 稳定引用类型

javascript 复制代码
const config = useMemo(() => ({ color: theme, size: "large" }), [theme]);

3. 避免子组件不必要渲染

javascript 复制代码
const MemoizedComponent = React.memo(Child);
function Parent() {
  const memoizedProps = useMemo(() => ({ onClick: handleClick }), []);
  return <MemoizedComponent {...memoizedProps} />;
}

与相关 Hook 的区别

特性 useMemo useEffect useCallback
执行时机 渲染阶段同步执行 浏览器绘制后异步执行 渲染阶段同步执行
主要用途 缓存计算结果 处理副作用 缓存函数引用
返回值 返回缓存值 无返回值 返回缓存函数
依赖数组作用 控制缓存更新 控制副作用触发 控制函数更新

注意事项

  1. 不要过度使用:仅在计算开销大或需要稳定引用时使用
  2. 引用类型比较 :默认使用浅比较,对于复杂对象可结合 JSON.stringify 或 Lodash 的 isEqual 实现深比较
  3. 组件内部使用useMemo 仅适用于单个组件内部,跨组件共享需使用状态管理库
  4. 引用稳定性useMemo 的真正价值在于保持数据引用的稳定性,而不仅是性能优化

代码示例

javascript 复制代码
function ComplexCalculation({ data }) {
  const result = useMemo(() => {
    console.log('重新计算');
    return data.reduce((acc, item) => acc + item.value, 0);
  }, [data]);

  return <div>总和: {result}</div>;
}

useMemo 是 React 性能优化的重要工具,但应合理使用,避免因过度优化导致代码复杂度增加。

相关推荐
前端小巷子3 分钟前
Web开发中的文件上传
前端·javascript·面试
翻滚吧键盘1 小时前
{{ }}和v-on:click
前端·vue.js
上单带刀不带妹1 小时前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
杨进军1 小时前
React 创建根节点 createRoot
前端·react.js·前端框架
ModyQyW2 小时前
用 AI 驱动 wot-design-uni 开发小程序
前端·uni-app
说码解字2 小时前
Kotlin lazy 委托的底层实现原理
前端
爱分享的程序员2 小时前
前端面试专栏-算法篇:18. 查找算法(二分查找、哈希查找)
前端·javascript·node.js
翻滚吧键盘2 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js
vim怎么退出2 小时前
万字长文带你了解微前端架构
前端·微服务·前端框架
你这个年龄怎么睡得着的2 小时前
为什么 JavaScript 中 'str' 不是对象,却能调用方法?
前端·javascript·面试