PureComponent

Ми рекомендуємо визначати компоненти як функції замість класів. Дивіться, як мігрувати.

PureComponent схожий на Component, але пропускає повторні рендеринги для тих самих пропсів та стану. Компоненти класів все ще підтримуються React, але ми не рекомендуємо використовувати їх у новому коді.

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

Довідник

PureComponent

Щоб пропустити повторний рендеринг компонента класу для тих самих пропсів та стану, розширте PureComponent замість Component:

import { PureComponent } from 'react';

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

PureComponent є підкласом Component і підтримує всі API Component. Розширення PureComponent еквівалентно визначенню власного методу shouldComponentUpdate, який неглибоко порівнює пропси та стан.

Дивіться більше прикладів нижче.


Використання

Пропуск непотрібних повторних рендерингів для компонентів класу

Зазвичай React повторно рендерить компонент, коли рендериться його батько. В якості оптимізації, ви можете створити компонент, який React не буде повторно рендерити, коли рендериться його батько, якщо його нові пропси і стан не відрізняються від старих пропсів і стану. Компоненти класу можуть обрати таку поведінку, розширивши PureComponent:

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

React-компонент завжди повинен мати чисту логіку рендерингу. Це означає, що він повинен повертати те саме виведення, якщо його пропси, стан та контекст не змінилися. Використовуючи PureComponent, ви повідомляєте React, що ваш компонент відповідає цій вимозі, тому React не потрібно повторно рендерити, поки його пропси та стан не змінилися. Однак, ваш компонент все одно буде повторно ререндерити, якщо зміниться контекст, який він використовує.

У цьому прикладі зверніть увагу, що компонент Greeting повторно рендериться щоразу, коли змінюється name (оскільки це один з його пропсів), але не тоді, коли змінюється address (оскільки він не передається Greeting як проп):

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} />
    </>
  );
}
label {
  display: block;
  margin-bottom: 16px;
}

Рекомендується визначати компоненти як функції замість класів. Дивіться, як мігрувати.


Альтернативи

Перехід від компонента класу PureComponent до функції

У новому коді рекомендується використовувати функціональні компоненти замість класових компонентів. Якщо у вас є деякі існуючі класові компоненти, що використовують PureComponent, ось як ви можете їх перетворити. Це оригінальний код:

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} />
    </>
  );
}
label {
  display: block;
  margin-bottom: 16px;
}

Коли ви перетворюєте цей компонент з класу на функцію, обгорніть його у memo:

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} />
    </>
  );
}
label {
  display: block;
  margin-bottom: 16px;
}

На відміну від PureComponent, memo не порівнює новий та старий стани. У функціональних компонентах виклик функції set з тим самим станом вже за замовчуванням запобігає повторному рендерингу, навіть без memo.