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() 来优化组件内的计算逻辑,避免重复计算,尤其是在计算复杂或耗时的场景中。

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

相关推荐
careybobo1 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)2 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端3 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡3 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木4 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!5 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
難釋懷5 小时前
JavaScript基础-移动端常见特效
开发语言·前端·javascript
还是鼠鼠5 小时前
Node.js全局生效的中间件
javascript·vscode·中间件·node.js·json·express
自动花钱机6 小时前
WebUI问题总结
前端·javascript·bootstrap·css3·html5