React.memo()和 useMemo()的用法是什么,有哪些区别

React.memo()React.useMemo() 是 React 中用于优化性能的两个工具,但它们的用途和实现方式有所不同。以下分别介绍它们的用法和区别。

1. React.memo()

用法

React.memo() 是一个高阶组件(HOC),由于react组件默认的渲染机制:只要父组件渲染子组件就会重新渲染

于是用于优化函数组件的渲染性能。它通过缓存组件的渲染结果,避免不必要的重新渲染。

作用

允许组件在Prop 没有改变的情况下跳过渲染

  • 基本语法

    tsx 复制代码
    const MemoizedComponent = React.memo(FunctionComponent);
  • 带比较函数的用法

    tsx 复制代码
    const MemoizedComponent = React.memo(FunctionComponent, arePropsEqual);

    其中,arePropsEqual 是一个比较函数,在使用memo缓存组件之后,react 会对每一个prop 使用Object.is 比较新值和老值 用于比较新旧 props 是否相等。如果返回 true,则组件不会重新渲染。

示例
tsx 复制代码
import React from 'react';

const MyComponent = ({ name }) => {
  console.log('Rendering MyComponent');
  return <div>Hello, {name}</div>;
};

const MemoizedComponent = React.memo(MyComponent);

const App = () => {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <MemoizedComponent name="Alice" />
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default App;

在这个例子中,MemoizedComponent 只会在 name 属性发生变化时重新渲染,而不会因为 count 的变化而重新渲染。

注意事项
  • React.memo() 只对组件的 props 进行浅比较。如果需要更复杂的比较逻辑,可以通过 arePropsEqual 函数来实现。
  • 它只适用于函数组件,不适用于类组件。
  • 它不会影响子组件的渲染行为,子组件仍然会根据自己的 props 或 state 变化而重新渲染。

2. React.useMemo()

用法

React.useMemo() 是一个 Hook,用于缓存计算结果,避免在组件重新渲染时重复计算。它通常用于优化性能,尤其是在计算复杂或耗时的场景中。

  • 基本语法

    tsx 复制代码
    const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);

    其中,computeExpensiveValue 是一个计算函数,[a, b] 是依赖数组,当依赖数组中的值发生变化时,才会重新计算。

示例
tsx 复制代码
import React, { useState, useMemo } from 'react';

const App = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');

  const expensiveCalculation = (num) => {
    console.log('Calculating...');
    return num * 2;
  };

  const memoizedValue = useMemo(() => expensiveCalculation(count), [count]);

  return (
    <div>
      <p>{`Name: ${name}`}</p>
      <p>{`Count: ${count}`}</p>
      <p>{`Memoized Value: ${memoizedValue}`}</p>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <button onClick={() => setName('Alice')}>Change Name</button>
    </div>
  );
};

export default App;

在这个例子中,expensiveCalculation 只会在 count 发生变化时重新计算,而不会因为 name 的变化而重新计算。

注意事项
  • useMemo 的依赖数组非常重要。如果依赖数组为空([]),则计算结果只会计算一次,类似于 useEffect 的空依赖数组。
  • 如果依赖数组中的值发生变化,useMemo 会重新计算并返回新的值。
  • useMemo 并不会阻止组件的重新渲染,它只是缓存计算结果,减少不必要的计算。

区别

特性 React.memo() React.useMemo()
用途 优化组件渲染性能,避免不必要的重新渲染 优化计算性能,缓存计算结果
适用对象 函数组件 函数组件内的计算逻辑
实现方式 高阶组件(HOC),通过比较 props 来决定是否重新渲染 Hook,通过缓存计算结果来避免重复计算
依赖数组 可选的 arePropsEqual 函数,用于自定义 props 比较逻辑 必须提供依赖数组,依赖数组中的值变化时重新计算
性能优化目标 避免组件的无意义渲染,减少 DOM 操作 避免重复计算,减少 CPU 资源消耗
使用场景 组件的 props 没有变化时,避免组件重新渲染 组件内的复杂计算逻辑,避免每次渲染都重新计算

总结

  • 使用 React.memo() 来优化组件的渲染性能,尤其是当组件的 props 没有变化时,避免不必要的重新渲染。
  • 使用 React.useMemo() 来优化组件内的计算逻辑,避免重复计算,尤其是在计算复杂或耗时的场景中。

根据具体的性能优化需求,选择合适的工具来提升应用的性能。

相关推荐
前端梭哈攻城狮4 分钟前
dify二开示例
前端·后端·python
该用户已不存在7 分钟前
Node.js 真的取代了PHP吗?
前端·后端·node.js
ze_juejin16 分钟前
JavaScript 的事件循环(Event Loop)机制
前端
前端缘梦20 分钟前
从源码到dist:拆解Webpack如何完成前端工程的"基因编译"
前端·webpack
热爱运维的小七25 分钟前
中型企业如何用 RUM 技术破解地理分布式用户体验难题?从指标监测到优化实操
前端·网站响应速度·地域访问
程序猿阿伟29 分钟前
《从点击到共鸣:论坛前端如何用交互细节编织用户体验》
前端·ux
樱花开了几轉29 分钟前
React中的合成事件解释和理解
前端·javascript·react.js
code_life33 分钟前
动态格式化时间
javascript
Hizuna35 分钟前
问题探索:某些场景下H5页面能够触发,而uniapp微信小程序不能触发
前端
一个很帅的帅哥1 小时前
Webpack 和 Vite 的关键区别
前端·webpack·前端框架·node.js