12k
All articles

Чистые компоненты в React: как они работают и когда их использовать

Чистые компоненты и React.memo используют поверхностное сравнение для пропуска лишних ре-рендеров; статья объясняет, когда применять каждый паттерн и как избегать проблем с референсами.

OpenReplay Team
OpenReplay Team
Чистые компоненты в React: как они работают и когда их использовать

Чистые компоненты в React полностью связаны с производительностью. Они помогают вашему приложению избегать ненужных повторных рендеров, проверяя, действительно ли изменились входные данные компонента (пропсы или состояние). В этой статье мы рассмотрим, как работают чистые компоненты, как их использовать и когда они полезны — с понятными, современными примерами.

Ключевые выводы

  • Узнайте, что делает компонент “чистым” в React
  • Посмотрите, когда использовать React.PureComponent или React.memo
  • Поймите поверхностное сравнение и его влияние на повторные рендеры

Что такое чистый компонент?

Чистый компонент — это компонент, который повторно рендерится только при изменении его пропсов или состояния. React определяет, нужно ли выполнять повторный рендер, выполняя поверхностное сравнение текущих пропсов/состояния с предыдущими.

Использование React.PureComponent

React.PureComponent — это эквивалент чистой функции для классовых компонентов. Он реализует встроенный метод shouldComponentUpdate(), который выполняет поверхностное сравнение.

class MyComponent extends React.PureComponent {
  render() {
    return <div>{this.props.text}</div>;
  }
}

Если this.props.text не изменился, компонент не будет повторно рендериться.

Функциональная альтернатива: React.memo

Для функциональных компонентов используйте React.memo().

const MyComponent = React.memo(function MyComponent({ text }) {
  return <div>{text}</div>;
});

React пропустит рендеринг, если text такой же, как и в предыдущем рендере.

Как работает поверхностное сравнение

Поверхностное сравнение означает:

  • Примитивные значения (например, числа или строки) сравниваются по значению
  • Объекты и массивы сравниваются по ссылке
{ a: 1 } === { a: 1 } // false
const obj = { a: 1 }
obj === obj // true

Таким образом, если вы передаете объект, который изменяется, а не пересоздается, чистый компонент может не заметить изменения.

Пример из реальной практики

Без оптимизации

const Item = ({ data }) => <div>{data.label}</div>;

Это будет повторно рендериться каждый раз, когда родительский компонент перерендеривается, даже если data не изменился.

С React.memo

const Item = React.memo(({ data }) => <div>{data.label}</div>);

Теперь компонент повторно рендерится только когда data является новым объектом.

Когда использовать PureComponent или memo

  • Вы рендерите списки с множеством элементов
  • Пропсы компонента остаются стабильными между рендерами
  • Вы хотите сократить циклы рендеринга в чувствительных к производительности частях вашего приложения
  • Вы используете useCallback или useMemo для сохранения ссылок

Распространенные ошибки

  • Поверхностное сравнение не обнаруживает глубокие изменения (вложенные объекты/массивы)
  • Не используйте его, если вы не уверены, что пропсы не изменяются незаметно
  • Может вызвать ошибки, если вы передаете нестабильные ссылки

React.memo vs React.PureComponent

Функция React.PureComponent React.memo Тип компонента Классовый компонент Функциональный компонент Логика сравнения Пропсы + состояние (поверхностное) Только пропсы (поверхностное) Пользовательская функция сравнения ❌ ✅ React.memo(fn) Современное использование Менее распространено Широко используется

Заключение

Чистые компоненты могут помочь React пропускать повторные рендеры и поддерживать производительность вашего UI — но они не являются панацеей. Предпочитайте React.memo для функциональных компонентов и понимайте, что при поверхностном сравнении важны ссылки. Используйте их, когда важна производительность и пропсы стабильны.

Часто задаваемые вопросы

В чем основное преимущество PureComponent?

Он предотвращает ненужные повторные рендеры, когда пропсы/состояние не изменились (используя поверхностное сравнение).

Когда следует использовать React.memo?

Используйте его, когда ваш функциональный компонент получает стабильные пропсы, и повторный рендеринг был бы расточительным.

Проверяет ли React.memo вложенные объекты?

Нет. Он использует поверхностное сравнение. Следует избегать мутации объектов или массивов на месте.

Listen to your bugs 🧘, with OpenReplay

See how users use your app and resolve issues fast.
Loved by thousands of developers

We use cookies to improve your experience. By using our site, you accept cookies.