Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
PureComponent в React
PureComponent — это базовый класс в React, который автоматически реализует неглубокое сравнение пропсов и состояния для оптимизации производительности. Это помощник для избежания ненужных перерисовок компонента.
Как работает PureComponent
PureComponent расширяет React.Component и переопределяет метод shouldComponentUpdate(), чтобы выполнить поверхностное сравнение (shallow comparison) пропсов и состояния:
class MyComponent extends React.PureComponent {
render() {
return <div>{this.props.name}</div>;
}
}
Когда компонент получает новые пропсы или состояние, React автоматически сравнивает старые и новые значения. Если они совпадают (по ссылке для объектов), компонент не перерисовывается.
Внутреннее поведение
// Эквивалент реализации shouldComponentUpdate в PureComponent:
shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState);
}
// shallowEqual сравнивает только первый уровень:
const shallowEqual = (obj1, obj2) => {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
return keys1.every(key => obj1[key] === obj2[key]);
};
Примеры использования
// До: обычный Component (всегда перерисовывается)
class UserCard extends React.Component {
render() {
return (
<div>
<h2>{this.props.name}</h2>
<p>{this.props.email}</p>
</div>
);
}
}
// После: PureComponent (перерисовывается только при изменении пропсов)
class UserCard extends React.PureComponent {
render() {
return (
<div>
<h2>{this.props.name}</h2>
<p>{this.props.email}</p>
</div>
);
}
}
Важные ограничения
Поверхностное сравнение означает, что для вложенных объектов и массивов сравниваются только ссылки:
// Проблема 1: Новый объект при каждом рендере
const user = { name: 'John', age: 30 };
<UserCard user={user} /> // Каждый раз новый объект
// Решение: Мемоизировать объект
const user = useMemo(() => ({ name: 'John', age: 30 }), []);
<UserCard user={user} />
// Проблема 2: Новые функции при каждом рендере
const handleClick = () => console.log('clicked');
<Button onClick={handleClick} /> // Каждый раз новая функция
// Решение: Используй useCallback или методы класса
class Parent extends React.PureComponent {
handleClick = () => console.log('clicked'); // Привязанный к экземпляру
render() {
return <Child onClick={this.handleClick} />;
}
}
Функциональные компоненты: React.memo
Для функциональных компонентов используй React.memo вместо PureComponent:
const UserCard = React.memo(({ name, email }) => (
<div>
<h2>{name}</h2>
<p>{email}</p>
</div>
));
// С кастомным сравнением:
const UserCard = React.memo(
({ name, email }) => <div>{name} - {email}</div>,
(prevProps, nextProps) => {
return prevProps.name === nextProps.name;
}
);
Когда использовать PureComponent
- Компонент имеет простые пропсы (примитивные типы)
- Высокая частота перерисовок родителя
- Компонент дорогой в рендеринге
- Уверены, что не будете передавать новые объекты/функции
Когда НЕ использовать
- Компонент использует вложенные объекты/массивы в пропсах
- Требуется кастомная логика сравнения
- Чаще всего нужно использовать
useMemoиuseCallbackвместо PureComponent
Современный подход
В современном React рекомендуется использовать функциональные компоненты с React.memo вместо PureComponent, так как это более гибко и понятно.