学习React-17-useMemo

React.memo

React.memo 是一个高阶组件(HOC),用于优化函数组件的渲染性能。它通过浅比较组件的 props 变化来决定是否重新渲染组件。如果 props 未变化,则复用上一次的渲染结果。

基本用法

将函数组件包裹在 React.memo 中即可:

ts 复制代码
const MyComponent = React.memo(function MyComponent(props) {
  // 组件逻辑
});

或使用箭头函数:

ts 复制代码
const MyComponent = React.memo((props) => {
  // 组件逻辑
});

自定义比较函数

默认情况下,React.memo 会对 props 进行浅比较。如果需要自定义比较逻辑,可以传入第二个参数:

ts 复制代码
const areEqual = (prevProps, nextProps) => {
  // 返回 true 表示跳过渲染,false 表示重新渲染
  return prevProps.value === nextProps.value;
};

const MyComponent = React.memo((props) => {
  // 组件逻辑
}, areEqual);

适用场景

  • 组件渲染开销较大(如复杂计算或频繁渲染)。
  • 父组件频繁更新,但子组件的 props 未变化。
  • 纯展示型组件(无内部状态或副作用)。

注意事项

  • 仅对 props 进行比较,不影响组件内部状态(state)或上下文(context)的变化。
  • 浅比较可能无法检测对象或数组内部的变化,需确保 props 是稳定引用。
  • 过度使用可能导致性能反而下降(比较逻辑本身消耗资源)。

与类组件的区别

类组件类似的功能可通过 React.PureComponent 或手动实现 shouldComponentUpdate 实现。React.memo 是函数组件的等效优化手段。

小栗子

ts 复制代码
import React, {useState} from 'react';
import './index.css';

interface userCard {
    name: string;
    age: number;
    phone: string;
}
// 未使用memo
// const Child = (props: {userData:userCard}) => {
// 使用memo
const Child = React.memo((props: {userData:userCard}) => {
    // 将userData解构出来
    const {userData} = props;

    console.log('子组件渲染了');
    return (
        <div className='userCard'>
            <p>{userData.name}</p>
            <p>{userData.age} 岁</p>
            <p>{userData.phone}</p>
        </div>
    )

})

export const App = () => {
    const [input, setInput] = useState('')
    const [user, setUser] = useState({
        name: '张三',
        age: 18,
        phone: '12345678901'
    })
    const handleBtnClick = () => {
        setUser({
            name: input,
            age: 18,
            phone: '12345678901'
        })
    }
    return (
        <div>
            <input 
                type="text" 
                value={input} 
                onChange={(e) => setInput(e.target.value)} 
                style={{
                    padding: '8px 12px',
                    border: '1px solid #000',
                    borderRadius: '4px',
                    fontSize: '14px',
                    marginRight: '8px'
                }}
            />
            <button 
                onClick={handleBtnClick}
                style={{
                    padding: '8px 16px',
                    backgroundColor: '#fff',
                    color: '#000',
                    border: '1px solid #000',
                    borderRadius: '4px',
                    cursor: 'pointer',
                    fontSize: '14px'
                }}
            >
                更改数据
            </button>
            <Child userData={user} />
        </div>
    )
}

export default App

结果如下:

在未使用memo时,只要state的值发生变化都会导致组件重新渲染,这样就很大程度上造成了资源的浪费。

使用memo之后,只有当子组件依赖的内容发生变化时才会重新去渲染。

useMemo

useMemo 是 React 中的一个 Hook,用于优化性能,通过缓存计算结果避免不必要的重复计算。它接受一个函数和依赖项数组,仅在依赖项发生变化时重新计算值。

useMemo 的语法

javascript 复制代码
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 第一个参数:计算函数,返回需要缓存的值。
  • 第二个参数:依赖项数组,数组中的值变化时才会重新计算(类似于useEffect)。

useMemo 的适用场景

优化计算密集型操作

当组件中有高开销的计算(如复杂数学运算、大数据处理)时,useMemo 可以避免每次渲染都重新计算。

避免不必要的子组件渲染

结合 React.memo 使用,可以防止子组件因父组件无关状态更新而重复渲染。

缓存引用类型数据

对于对象或数组等引用类型,useMemo 可以避免每次渲染生成新引用,减少子组件的不必要更新。

useMemo 的注意事项

避免过度使用
useMemo 本身有性能开销,仅在高开销计算或引用稳定性关键时使用。简单计算可能得不偿失。

依赖项需明确

遗漏依赖项可能导致缓存值不更新,错误地使用旧值。确保依赖项完整且准确。

不用于副作用
useMemo 应用于纯计算逻辑,副作用(如数据请求、DOM 操作)应使用 useEffect

useMemo 与 useCallback 的区别

  • useMemo 缓存计算结果(如数值、对象)。
  • useCallback 缓存函数本身,避免函数引用变化。

代码示例

javascript 复制代码
import React, { useMemo, useState } from 'react';

function Sum({ n }) {
  // 使用useMemo(数据处理的方法, [依赖项]),只有当依赖项发生改变时才会重新执行数据处理方法  返回值:useMemo返回的时普通值
  const total = useMemo(() => {
    console.log('重新计算和');
    return (n * (n + 1)) / 2;
  }, [n]);

  return <h1>1+2+...+{n} = {total}</h1>;
}

export default function App() {
  const [n, setN] = useState(5);
  const [v, setV] = useState(0);   // 与计算无关的状态

  return (
    <>
      <Sum n={n} />
      <button onClick={() => setN(n + 1)}>n+1</button>
      <button onClick={() => setV(v + 1)}>无关渲染 {v}</button>
    </>
  );
}

通过合理使用 useMemo,可以显著提升 React 组件的性能表现。

相关推荐
千寻girling2 小时前
记录第一次学习 Docker
学习·docker·容器
ShoaibShokat032 小时前
React 19 + TypeScript 实战:把 Ludo 游戏拆成纯引擎、状态层和可替换网络层
react.js
Yeats_Liao2 小时前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis
Kobebryant-Manba3 小时前
学习RNN(简洁实现)
人工智能·rnn·学习
我是真菜3 小时前
彻底理解js中的深浅拷贝
前端·javascript
知南x3 小时前
【DPDK例程学习】(4) l2fwd
学习·word
kisdiem3 小时前
ReAct:让大模型一边推理,一边行动
前端·react.js·前端框架
努力努力再努力FFF3 小时前
大学四年AI能力规划:从入门学习到简历表达
人工智能·学习
Litluecat3 小时前
配合多角色提示语3,学习AI漫剧(刚开始学)
人工智能·学习·ai·提示词·短剧·漫剧
三品吉他手会点灯4 小时前
STM32F103 学习笔记-24-I2C-读写EEPROM(第1节)-I2C物理层介绍
笔记·stm32·学习