【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 性能优化的重要工具,但应合理使用,避免因过度优化导致代码复杂度增加。

相关推荐
爱读源码的大都督7 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝7 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员7 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_7 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
ITOM运维行者7 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端
monologues7 小时前
深入 Vue 3 源码:响应式系统的精妙设计与编译优化
前端
hunterandroid7 小时前
Paging 3 分页:从手动分页到声明式加载
前端
用户4099322502127 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端
Csvn8 小时前
CSS :has() 选择器实战:没有它之前我们写了多少冗余 JS
前端·css
梨子同志8 小时前
TypeScript
前端