自学内容网 自学内容网

如何使用 useMemo 和 memo 优化 React 应用性能?

使用 useMemomemo 优化 React 应用性能

在构建复杂的 React 应用时,性能优化是确保应用流畅运行的关键。React 提供了多种工具来帮助开发者优化组件的渲染和计算逻辑,其中 useMemomemo 是两个非常有用的 Hook。本文将详细介绍这两个工具的使用方法及其应用场景。

1. useMemo 的介绍与使用

1.1 什么是 useMemo

useMemo 是一个 React Hook,用于记忆(缓存)某些计算结果,以避免不必要的重复计算。它接收两个参数:一个返回值的计算函数和一个依赖项数组。只有当依赖项发生变化时,useMemo 才会重新计算并返回新的值;否则,它将返回之前缓存的结果。

1.2 useMemo 的语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • computeExpensiveValue(a, b) 是一个计算昂贵值的函数。
  • [a, b] 是依赖项数组,只有当这些依赖项发生变化时,useMemo 才会重新执行计算。
1.3 示例:优化总价计算

在你的 Test2.tsx 组件中,total 函数用于计算商品的总价。每次组件重新渲染时,total 都会重新计算。为了优化这一点,我们可以使用 useMemo 来缓存计算结果:

import React, { useState, useMemo } from 'react';

export default function Test2() {
  const [search, setSearch] = useState('');
  const [list, setList] = useState([
    { id: 1, name: '苹果', price: 10, count: 1 },
    { id: 2, name: '小米', price: 20, count: 1 },
    { id: 3, name: '华为', price: 30, count: 1 },
  ]);

  const handleAdd = (id: number) => {
    setList(list.map(item => item.id === id ? { ...item, count: item.count + 1 } : item));
  };

  const handleSub = (id: number) => {
    setList(list.map(item => item.count > 1 && item.id === id ? { ...item, count: item.count - 1 } : item));
  };

  // 使用 useMemo 缓存总价计算结果
  const total = useMemo(() => {
    return list.reduce((pre, cur) => pre + cur.price * cur.count, 0);
  }, [list]);

  return (
    <div>
      <h1>父组件</h1>
      <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} />
      <table border={1} cellPadding={5} cellSpacing={0}>
        <thead>
          <tr>
            <th>商品名称</th>
            <th>商品价格</th>
            <th>商品数量</th>
          </tr>
        </thead>
        <tbody>
          {list.map(item => (
            <tr key={item.id}>
              <td>{item.name}</td>
              <td>{item.price * item.count}</td>
              <td>
                <button onClick={() => handleAdd(item.id)}>+</button>
                <span>{item.count}</span>
                <button onClick={() => handleSub(item.id)}>-</button>
              </td>
            </tr>
          ))}
        </tbody>
        <tfoot>
          <tr>
            <th scope="row" colSpan={1}>总价</th>
            <td>{total}</td>
          </tr>
        </tfoot>
      </table>
    </div>
  );
}

在这个例子中,useMemo 确保只有当 list 发生变化时才会重新计算 total,从而减少了不必要的计算开销。

2. memo 的介绍与使用

2.1 什么是 memo

memo 是 React 提供的一个高阶组件(HOC),用于防止子组件不必要的重新渲染。它通过比较当前和上次渲染的 props 来决定是否需要重新渲染组件。如果 props 没有变化,则跳过渲染,直接复用之前的渲染结果。

2.2 memo 的语法
const MemoizedComponent = React.memo(MyComponent);
  • MyComponent 是你想要优化的组件。
  • React.memo 返回一个新的组件,该组件会在 props 没有变化时不重新渲染。
2.3 示例:优化子组件渲染

假设我们有一个子组件 ProductItem,它负责显示单个商品的信息。我们可以使用 memo 来优化这个组件,避免不必要的重新渲染:

import React from 'react';
import { memo } from 'react';

interface ProductItemProps {
  product: { id: number; name: string; price: number; count: number };
  onAdd: () => void;
  onSub: () => void;
}

const ProductItem: React.FC<ProductItemProps> = ({ product, onAdd, onSub }) => {
  console.log('ProductItem rendered');
  return (
    <tr key={product.id}>
      <td>{product.name}</td>
      <td>{product.price * product.count}</td>
      <td>
        <button onClick={onAdd}>+</button>
        <span>{product.count}</span>
        <button onClick={onSub}>-</button>
      </td>
    </tr>
  );
};

// 使用 memo 包装 ProductItem 组件
const MemoizedProductItem = memo(ProductItem);

export default MemoizedProductItem;

在这个例子中,MemoizedProductItem 只会在其 props 发生变化时重新渲染,否则会复用之前的渲染结果,从而提高性能。

3. useMemomemo 的区别

  • 作用范围

    • useMemo 用于优化组件内部的计算逻辑,减少不必要的计算。
    • memo 用于优化组件的渲染行为,减少不必要的重新渲染。
  • 使用场景

    • 当你在组件内部有复杂的计算逻辑时,可以使用 useMemo 来缓存计算结果。
    • 当你有一个子组件频繁重新渲染但实际内容没有变化时,可以使用 memo 来优化渲染性能。

4. 总结

useMemomemo 是 React 中非常强大的工具,能够显著提升应用的性能。合理使用它们可以帮助你避免不必要的计算和渲染,从而让应用更加高效和流畅。希望本文能帮助你更好地理解和使用这两个工具,为你的 React 应用带来更好的用户体验。


原文地址:https://blog.csdn.net/qq_46032105/article/details/145206261

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!