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

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

相关推荐
Mintopia几秒前
Three.js 制作飘摇的草:从基础到进阶的全流程教学
前端·javascript·three.js
BillKu几秒前
Vue3父子组件数据双向同步实现方法
前端·javascript·vue.js
红尘散仙20 分钟前
七、WebGPU 基础入门——Texture 纹理
前端·rust·gpu
jaywongX21 分钟前
Base64编码原理:二进制数据与文本的转换技术
前端·javascript·vue
红尘散仙21 分钟前
八、WebGPU 基础入门——加载图像纹理
前端·rust·gpu
佳腾_24 分钟前
【Web应用服务器_Tomcat】一、Tomcat基础与核心功能详解
java·前端·中间件·tomcat·web应用服务器
天天扭码39 分钟前
深入讲解Javascript中的常用数组操作函数
前端·javascript·面试
猿究院_xyz40 分钟前
跟着尚硅谷学vue-day5
前端·javascript·vue.js·前端框架·html
小杰love编程43 分钟前
Django 入门指南:构建强大的 Web 应用程序
前端·django·sqlite
~heart将心比心1 小时前
chrome://inspect/#devices 调试 HTTP/1.1 404 Not Found 如何解决
前端·chrome