React 中hooks之 React.memo 和 useMemo用法示例总结

 更新时间:2025年01月23日 14:22:34   作者:傻小胖  
React.memo是一个高阶组件,用于优化函数组件的性能,通过记忆组件渲染结果来避免不必要的重新渲染,合理使用React.memo和useMemo可以显著提升React应用的性能,本文介绍React 中hooks之 React.memo 和 useMemo用法总结,感兴趣的朋友一起看看吧

1. React.memo 基础

React.memo 是一个高阶组件(HOC),用于优化函数组件的性能,通过记忆组件渲染结果来避免不必要的重新渲染。

1.1 基本用法

const MemoizedComponent = React.memo(function MyComponent(props) {
  /* 渲染逻辑 */
});

只有props发生变化才会重新渲染MemoizedComponent

1.2 带有比较函数的用法

const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
  // 返回 true 表示不需要重新渲染
  // 返回 false 表示需要重新渲染
  return prevProps.id === nextProps.id;
});

2. React.memo 使用场景

2.1 纯展示组件

const ExpensiveComponent = React.memo(function ExpensiveComponent({ data }) {
  // 复杂的渲染逻辑
  return (
    <div>
      {data.map(item => (
        <div key={item.id}>
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </div>
      ))}
    </div>
  );
});
// 父组件
function ParentComponent() {
  const [count, setCount] = useState(0);
  const data = [/* 大量数据 */];
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>
        Count: {count}
      </button>
      <ExpensiveComponent data={data} />
    </div>
  );
}

2.2 列表项组件

const ListItem = React.memo(function ListItem({ item, onItemClick }) {
  console.log(`Rendering item ${item.id}`);
  return (
    <li onClick={() => onItemClick(item.id)}>
      {item.name}
    </li>
  );
});
function List({ items }) {
  const [selectedId, setSelectedId] = useState(null);
  // 使用 useCallback 来记忆回调函数
  const handleItemClick = useCallback((id) => {
    setSelectedId(id);
  }, []);
  return (
    <ul>
      {items.map(item => (
        <ListItem
          key={item.id}
          item={item}
          onItemClick={handleItemClick}
        />
      ))}
    </ul>
  );
}

3. useMemo 基础

useMemo 是一个 Hook,用于记忆计算结果,避免在每次渲染时重复进行昂贵的计算。

3.1 基本用法

const memoizedValue = useMemo(() => {
  // 进行计算并返回结果
  return computeExpensiveValue(a, b);
}, [a, b]); // 依赖项数组,空数组时只有初始化的时候执行,没有依赖参数项state每次变化都会引起重新执行,有依赖数组室,依赖数据发生变化才会触发重新执行

4. useMemo 使用场景

4.1 昂贵的计算

function DataAnalytics({ data }) {
  const processedData = useMemo(() => {
    // 假设这是一个复杂的数据处理函数
    return data.map(item => ({
      ...item,
      processed: expensiveOperation(item)
    }));
  }, [data]); // 只在 data 改变时重新计算
  return (
    <div>
      {processedData.map(item => (
        <div key={item.id}>{item.processed}</div>
      ))}
    </div>
  );
}

4.2 避免子组件不必要的重新渲染

function ParentComponent({ items }) {
  // 记忆对象或数组类型的 props
  const memoizedValue = useMemo(() => ({
    data: items,
    config: {
      sortBy: 'name',
      filterBy: 'active'
    }
  }), [items]);
  return <ChildComponent options={memoizedValue} />;
}

4.3 复杂对象的派生状态

function UserDashboard({ user, transactions }) {
  // 计算用户统计信息
  const userStats = useMemo(() => {
    return {
      totalSpent: transactions.reduce((sum, t) => sum + t.amount, 0),
      averageSpent: transactions.length
        ? transactions.reduce((sum, t) => sum + t.amount, 0) / transactions.length
        : 0,
      mostFrequentCategory: calculateMostFrequentCategory(transactions)
    };
  }, [transactions]);
  return (
    <div>
      <UserInfo user={user} />
      <UserStatistics stats={userStats} />
    </div>
  );
}

5. 性能优化最佳实践

5.1 合理使用 React.memo

// ✅ 好的使用场景:纯组件,props 很少改变
const PureComponent = React.memo(function PureComponent({ data }) {
  return <div>{/* 渲染逻辑 */}</div>;
});
// ❌ 不好的使用场景:props 经常变化
const FrequentlyChangingComponent = React.memo(function FrequentlyChangingComponent({ date }) {
  return <div>{date.toLocaleTimeString()}</div>;
});

5.2 合理使用 useMemo

// ✅ 好的使用场景:计算开销大
const expensiveValue = useMemo(() => {
  return someExpensiveOperation(props.data);
}, [props.data]);
// ❌ 不好的使用场景:计算开销小
const simpleValue = useMemo(() => {
  return props.value + 1;
}, [props.value]); // 这种情况直接计算即可

5.3 配合 useCallback 使用

function SearchComponent({ onSearch }) {
  const [query, setQuery] = useState('');
  // 记忆回调函数
  const handleSearch = useCallback(() => {
    onSearch(query);
  }, [query, onSearch]);
  // 记忆计算结果
  const searchResults = useMemo(() => {
    return performExpensiveSearch(query);
  }, [query]);
  return (
    <div>
      <input
        value={query}
        onChange={e => setQuery(e.target.value)}
      />
      <button onClick={handleSearch}>搜索</button>
      <ResultsList results={searchResults} />
    </div>
  );
}
// 使用 React.memo 优化 ResultsList
const ResultsList = React.memo(function ResultsList({ results }) {
  return (
    <ul>
      {results.map(result => (
        <li key={result.id}>{result.title}</li>
      ))}
    </ul>
  );
});

6. 注意事项

不要过度优化

  • 只在真正需要的地方使用 memo 和 useMemo
  • 性能测量验证优化效果

依赖项的正确使用

  • 确保依赖项数组包含所有需要的值
  • 避免依赖项过多导致优化失效

避免在循环中使用 useMemo

// ❌ 错误示例
{items.map(item => {
  const memoizedValue = useMemo(() => compute(item), [item]);
  return <div>{memoizedValue}</div>;
})}

考虑内存使用

  • memo 和 useMemo 会占用额外的内存
  • 在内存受限的环境中要谨慎使用

7. 性能优化决策流程

  • 首先评估是否真的需要优化
  • 使用 React DevTools Profiler 识别性能问题
  • 选择合适的优化策略:
    • 组件重新渲染优化:使用 React.memo
    • 计算结果优化:使用 useMemo
    • 回调函数优化:使用 useCallback
  • 测试优化效果
  • 持续监控性能

通过合理使用 React.memo 和 useMemo,我们可以显著提升 React 应用的性能。但记住,过度优化可能会适得其反,应该在实际需要时才进行优化。

到此这篇关于React 中hooks之 React.memo 和 useMemo用法总结的文章就介绍到这了,更多相关React React.memo 和 useMemo内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React-Native之定时器Timer的实现代码

    React-Native之定时器Timer的实现代码

    本篇文章主要介绍了React-Native之定时器Timer的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 如何在React中直接使用Redux

    如何在React中直接使用Redux

    这篇文章主要介绍了如何在React中直接使用Redux,目前redux在react中使用是最多的,所以我们需要将之前编写的redux代码,融入到react当中去,本文给大家详细讲解,需要的朋友可以参考下
    2022-11-11
  • react数据管理中的setState与Props详解

    react数据管理中的setState与Props详解

    setState 是 React 中用于更新组件状态(state)的方法,本文给大家介绍react数据管理中的setState与Props知识,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • react hooks 计数器实现代码

    react hooks 计数器实现代码

    这篇文章主要介绍了react hooks计数器实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • React实现语音识别并转换功能

    React实现语音识别并转换功能

    在现代 Web 开发中,语音识别技术的应用越来越广泛,本文将介绍如何使用 React 实现一个简单的语音识别并转换的功能,有需要的小伙伴可以了解下
    2025-05-05
  • react实现组件状态缓存的示例代码

    react实现组件状态缓存的示例代码

    本文主要介绍了react实现组件状态缓存的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • React弹窗使用方式NiceModal重新思考

    React弹窗使用方式NiceModal重新思考

    这篇文章主要为大家介绍了React弹窗使用方式NiceModal重新思考分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 详解React 的数据流和生命周期

    详解React 的数据流和生命周期

    这篇文章主要介绍了React 的数据流和生命周期,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • ReactJS实现表单的单选多选和反选的示例

    ReactJS实现表单的单选多选和反选的示例

    本篇文章主要介绍了ReactJS实现表单的单选多选和反选的示例,非常具有实用价值,需要的朋友可以参考下
    2017-10-10
  • 浅谈React双向数据绑定原理

    浅谈React双向数据绑定原理

    在 React中是不存在双向数据绑定的机制的,需要我们自己对其进行实现。本文主要介绍一下React双向数据绑定,感兴趣的可以了解一下
    2021-11-11

最新评论