Чистые компоненты в 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
для функциональных компонентов и понимайте, что при поверхностном сравнении важны ссылки. Используйте их, когда важна производительность и пропсы стабильны.
Часто задаваемые вопросы
Он предотвращает ненужные повторные рендеры, когда пропсы/состояние не изменились (используя поверхностное сравнение).
Используйте его, когда ваш функциональный компонент получает стабильные пропсы, и повторный рендеринг был бы расточительным.
Нет. Он использует поверхностное сравнение. Следует избегать мутации объектов или массивов на месте.