如何避免 React 组件不必要的重新渲染?

优化 React 组件性能以避免不必要的重新渲染。

React 中等 性能 性能优化 组件

为了避免不必要的重新渲染并优化性能,可以通过多种技巧管理和控制组件的渲染行为。常见方法包括使用内置的 React API 来处理数据缓存和控制渲染逻辑:

主要优化技巧

  1. 使用 React.memo 缓存组件
    React.memo 是一款高阶组件,用于功能组件。它通过浅比较 props 的变化来决定组件是否需要重新渲染。这适用于子组件在 props 不变时避免继承父组件的不必要更新。
    import React, { memo } from 'react';
    const MemoizedChild = memo(function Child({ name }) {
      return <div>{name}</div>;
    });
    export default MemoizedChild;
    
  2. 使用 useCallback 缓存引用类型函数
    useCallback 用于缓存函数引用,防止其引用在每次渲染时改变,从而避免依赖这些函数的子组件被无效重新渲染。适用于事件处理器或高阶函数。
    import { useState, useCallback } from 'react';
    function Parent() {
      const [count, setCount] = useState(0);
      const handleClick = useCallback(() => setCount(prev => prev + 1), []);
      return <button onClick={handleClick}>Click</button>;
    }
    
  3. 使用 useMemo 缓存计算值
    useMemo 对复杂计算结果实施缓存,当依赖项无变化时避免重复运行计算逻辑。适用于减少渲染中的重复计算代价。
    import { useMemo } from 'react';
    function Child({ data }) {
      const formattedData = useMemo(() => data.map(item => item.name), [data]);
      return <div>{formattedData}</div>;
    }
    
  4. 使用 PureComponent 和 shouldComponentUpdate(类组件优化)
    类组件可通过 PureComponent (基于浅比较 stateprops) 覆盖 shouldComponentUpdate 生命周期函数。自定义比较逻辑允许开发者控制是否重新渲染。
    import { PureComponent } from 'react';
    class OptimizedClassComponent extends PureComponent {
      render() {
        return <div>{this.props.value}</div>;
      }
    }
    
  5. 拆分组件和使用状态下放(State Colocation)
    将状态拆分到较小的组件中,只将所需状态提升到高层,减少数据变化的影响范围。在父组件的无关状态变更时保护子组件不被联动渲染。
    function Parent() {
      const [user, setUser] = useState({ name: 'Bob' });
      return (
        <div>
          <Child user={user} />
          <button onClick={() => setCount(prev => prev + 1)}>Increment</button>
        </div>
      );
    }
    

其他补充技巧

  • 使用唯一 key 优化列表渲染:在 map 或迭代生成组件时为项添加唯一的 key,帮助高效重新排序。
  • 性能分析工具:结合 React DevTools 监控渲染成本,识别不必要渲染点。

通过合适方法的组合,可显著降低应用加载延迟和 CPU 负载。