Що робить shouldComponentUpdate()?
Визначення
shouldComponentUpdate(nextProps, nextState)
- це метод життєвого циклу, який викликається перед повторним рендером. Він повинен повернути
trueабоfalse, щоб React зрозумів, чи потрібно виконуватиrender().
Коли викликається
Послідовність при оновленні компонента:
props/state змінилися
↓
shouldComponentUpdate() ← викликається
↓ (якщо повернув true)
render()
↓
commit phase → componentDidUpdate()Якщо метод повертає false, React пропускає render і commit-фазу для цього компонента та його нащадків.
Сигнатура
shouldComponentUpdate(nextProps, nextState) {
// повернути true → компонент перерендериться
// повернути false → React пропустить оновлення
}| Аргумент | Що містить |
|---|---|
nextProps | Нові пропси, які компонент має отримати |
nextState | Новий стан (state), який буде встановлено |
Приклад
class Counter extends React.Component {
state = { count: 0 };
shouldComponentUpdate(nextProps, nextState) {
// Перерендер тільки якщо count змінився
return nextState.count !== this.state.count;
}
render() {
console.log('render');
return (
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
{this.state.count}
</button>
);
}
}Що відбувається:
- При
setStateReact викликаєshouldComponentUpdate(nextProps, nextState). - Якщо повертається
true-> React викликаєrender(). - Якщо
false-> React пропускає перемальовку.
Приклад з пропсами
class UserCard extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.user.id !== this.props.user.id; // порівняння за id
}
render() {
console.log('render');
return <div>{this.props.user.name}</div>;
}
}Якщо батьківський компонент щоразу передає новий об'єкт user, але з тим самим id,
і shouldComponentUpdate поверне false, то React не буде ререндерити компонент.
Важливо пам'ятати
- Метод повинен бути чистим - не викликати побічні ефекти, не змінювати стан.
- Не викликається при монтуванні, тільки при оновленнях.
- React ігнорує його, якщо використовується
PureComponent(у ньому вже реалізовано "поверхневе порівняння").
Аналог у функціональних компонентах
У функціональних компонентах shouldComponentUpdate не існує напряму.
Але його поведінку можна відтворити через:
React.memo()
const UserCard = React.memo(function UserCard({ user }) {
console.log('render');
return <div>{user.name}</div>;
});React.memo робить те саме - поверхнево порівнює старі і нові props. Якщо однакові - не викликає компонент заново.
Кастомне порівняння (аналог shouldComponentUpdate)
const UserCard = React.memo(
function UserCard({ user }) {
console.log('render');
return <div>{user.name}</div>;
},
(prevProps, nextProps) => prevProps.user.id === nextProps.user.id
);Тут другий аргумент (areEqual) - це інвертована логіка порівняно з shouldComponentUpdate:
якщо areEqual() повертає true, компонент не оновлюється.
Типові сценарії використання
| Мета | Приклад |
|---|---|
| Оптимізація продуктивності | Уникнути зайвих перерендерів при передачі незмінних даних |
| Контроль оновлення | Оновлювати компонент тільки при зміні конкретного поля |
| Порівняння пропсів | Реалізувати глибоке або точкове порівняння даних |
Порівняння з іншими оптимізаціями
| Підхід | Де використовується | Що робить |
|---|---|---|
shouldComponentUpdate() | Класові компоненти | Повний контроль, вручну |
React.PureComponent | Класові компоненти | Вбудоване поверхневе порівняння |
React.memo() | Функціональні компоненти | Аналог PureComponent |
useMemo() / useCallback() | Функціональні компоненти | Мемоізація значень і функцій, щоб не змінювати посилання і не тригерити оновлення |
Підсумок
shouldComponentUpdate()дозволяє вручну контролювати, чи повинен React перерендерити компонент при змініpropsабоstate.
Якщо повертаєш false ->
React пропускає render і commit, економить ресурси, підвищує продуктивність.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.