React-SCU、PureComponent、memo

React-SCU、PureComponent、memo


react 性能优化 前端

比如有以下代码:

import React, { Component } from "react";
import Banner from "./Banner";
import Home from "./Home";

export class ComponentPerformance extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "Niko",
    };
  }
  changeName() {
    this.setState((state) => {
      return {
        name: state.name,
      };
    });
  }
  render() {
    console.log("App render");
    const { name } = this.state;
    return (
      <div>
        <h2>{name}</h2>
        <button
          onClick={(e) => {
            this.changeName();
          }}
        >
          改名字
        </button>
        <Home></Home>
        <Banner></Banner>
      </div>
    );
  }
}

export default ComponentPerformance;

当我们调用 setState 修改 state 中的值的时候,会触发 render,此时 Home 和 Banner 组件也会触发各自的 render,但是此时子组件并不依赖父组件的值,所以这次 render 是没有必要的,会对性能造成一定影响。

shouldComponentUpdate(SCU)

React 提供了一个生命周期 shouldComponentUpdate,该方法有两个参数

  • nextProps 修改后最新的 props 属性
  • nextState 修改后最新的 state 属性

该方法返回值是一个 boolean

  • 返回 true,则需要调用 render,默认是 true
  • 返回 false,不需要调用 render

可以通过在该方法内判断 nextProps/nextState 中的值是否与 this.props/this.state 中的值相同,来返回 true/false 控制 render 的执行,提高性能。

PureComponent

当然实际开发中,如果这么写的话,需要判断太多字段了,所以 React 提供了一个 PureComponent,类组件只需要继承自PureComponent,就可以达到上面的效果。

PureComponent实际是对新旧 state 和新旧 props 做了一次浅层比较,即

return !shallowEqual(state, nextState) || !shallowEqual(props, nextProps);

返回 true 时就会 re-renderPureComponent的原型上会有一个标识,在通过继承自它的类创建的实例上,通过原型链也会找到这个标识,通过这个标识判断是否这样去判断。如果自身实现了 SCU 方法,会先判断SCU方法的返回值。

memo

PureComponent是在类组件中使用的,如果是函数组件,就需要使用 memo 了。

import React, { memo } from "react";

const Footer = memo((props) => {
  console.log("Footer render");
  return <div>{props.name}</div>;
});

export default Footer;

就是因为内部是使用浅层比较做的判断是否需要re-render, 所以在 setState 的时候,对于对象类型,不要直接修改其值然后 setState,这样在判断的时候由于内存地址相同而不会触发更新。

© 2025 Niko Xie