易犯错误

我们建议将组件定义为函数而不是类。查看如何迁移。

¥We recommend defining components as functions instead of classes. See how to migrate.

PureComponentComponent 类似,但它会跳过具有相同属性和状态的重新渲染。React 仍然支持类组件,但我们不建议在新代码中使用它们。

¥PureComponent is similar to Component but it skips re-renders for same props and state. Class components are still supported by React, but we don’t recommend using them in new code.

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

参考

¥Reference

PureComponent

要避免为相同的属性和状态重新渲染类组件,请扩展 PureComponent 而不是 Component

¥To skip re-rendering a class component for same props and state, extend PureComponent instead of Component:

import { PureComponent } from 'react';

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

PureComponentComponent 的子类,并支持 所有 Component API。。扩展 PureComponent 相当于定义一个自定义的 shouldComponentUpdate 方法,该方法对属性和状态进行浅层比较。

¥PureComponent is a subclass of Component and supports all the Component APIs. Extending PureComponent is equivalent to defining a custom shouldComponentUpdate method that shallowly compares props and state.

请参阅下面的更多示例。

¥See more examples below.


用法

¥Usage

跳过类组件不必要的重新渲染

¥Skipping unnecessary re-renders for class components

React 通常会在父级重新渲染时重新渲染组件。作为一项优化,你可以创建一个组件,只要其新的属性和状态与旧的属性和状态相同,React 就不会在其父组件重新渲染时重新渲染该组件。类组件 可以通过扩展 PureComponent 来选择此行为:

¥React normally re-renders a component whenever its parent re-renders. As an optimization, you can create a component that React will not re-render when its parent re-renders so long as its new props and state are the same as the old props and state. Class components can opt into this behavior by extending PureComponent:

class Greeting extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}

React 组件应该总是有 纯渲染逻辑。 这意味着如果它的属性、状态和上下文没有改变,它必须返回相同的输出。通过使用 PureComponent,你可以告诉 React 你的组件符合此要求,因此只要其属性和状态没有改变,React 就无需重新渲染。但是,如果组件使用的上下文发生变化,它仍然会重新渲染。

¥A React component should always have pure rendering logic. This means that it must return the same output if its props, state, and context haven’t changed. By using PureComponent, you are telling React that your component complies with this requirement, so React doesn’t need to re-render as long as its props and state haven’t changed. However, your component will still re-render if a context that it’s using changes.

在此示例中,请注意 Greeting 组件会在 name 发生更改时重新渲染(因为这是它的属性之一),但不会在 address 更改时重新渲染(因为它没有作为属性传递给 Greeting):

¥In this example, notice that the Greeting component re-renders whenever name is changed (because that’s one of its props), but not when address is changed (because it’s not passed to Greeting as a prop):

import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

易犯错误

我们建议将组件定义为函数而不是类。查看如何迁移。

¥We recommend defining components as functions instead of classes. See how to migrate.


备选方案

¥Alternatives

PureComponent 类组件从 PureComponent 迁移到函数

¥Migrating from a PureComponent class component to a function

我们建议在新代码中使用函数组件而不是 类组件。如果你有一些使用 PureComponent 的现有类组件,你可以按照以下方法进行转换。这是原始代码:

¥We recommend using function components instead of class components in new code. If you have some existing class components using PureComponent, here is how you can convert them. This is the original code:

import { PureComponent, useState } from 'react';

class Greeting extends PureComponent {
  render() {
    console.log("Greeting was rendered at", new Date().toLocaleTimeString());
    return <h3>Hello{this.props.name && ', '}{this.props.name}!</h3>;
  }
}

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

import { memo, useState } from 'react';

const Greeting = memo(function Greeting({ name }) {
  console.log("Greeting was rendered at", new Date().toLocaleTimeString());
  return <h3>Hello{name && ', '}{name}!</h3>;
});

export default function MyApp() {
  const [name, setName] = useState('');
  const [address, setAddress] = useState('');
  return (
    <>
      <label>
        Name{': '}
        <input value={name} onChange={e => setName(e.target.value)} />
      </label>
      <label>
        Address{': '}
        <input value={address} onChange={e => setAddress(e.target.value)} />
      </label>
      <Greeting name={name} />
    </>
  );
}

注意

PureComponent 不同,memo 不会比较新旧状态。在函数组件中,即使没有 memo,也可以使用与 默认情况下已阻止重新渲染, 相同的状态调用 set 函数

¥Unlike PureComponent, memo does not compare the new and the old state. In function components, calling the set function with the same state already prevents re-renders by default, even without memo.