Skip to main content

Чим React.memo() схожий на shouldComponentUpdate()?

Загальна ідея

І React.memo(), і shouldComponentUpdate() дозволяють контролювати, чи має компонент перерендерюватися, якщо його props не змінилися.

Обидва потрібні для оптимізації продуктивності - щоб уникнути зайвих ререндерів, коли компонент отримує ті самі дані.


shouldComponentUpdate() - у класових компонентах

Це метод життєвого циклу, який викликається перед повторним рендером:

javascript
class User extends React.Component { shouldComponentUpdate(nextProps, nextState) { // повернути false → React пропустить render() return nextProps.name !== this.props.name; } render() { console.log('рендер'); return <div>{this.props.name}</div>; } }

Якщо метод повертає:

  • true -> React викликає render() і оновлює компонент;
  • false -> React пропускає рендер і не чіпає DOM.

React.memo() - у функціональних компонентах

Це HOC (Higher-Order Component), який робить для функціональних компонентів те саме, що shouldComponentUpdate робить для класових.

javascript
const User = React.memo(function User({ name }) { console.log('рендер'); return <div>{name}</div>; });

За замовчуванням React.memo робить поверхневе порівняння пропсів. Якщо старі і нові пропси ідентичні (за Object.is), компонент не буде перерендерений.


Тобто:

КомпонентМеханізмКонтроль
КласовийshouldComponentUpdate(nextProps, nextState)Повертаєш true / false
ФункціональнийReact.memo(Component, areEqual?)Другий аргумент - функція порівняння пропсів

Кастомне порівняння в React.memo

Якщо потрібно - можна явно вказати кастомну логіку порівняння (аналог ручного shouldComponentUpdate):

javascript
const User = React.memo( function User({ name, age }) { console.log('рендер'); return <div>{name} ({age})</div>; }, (prevProps, nextProps) => prevProps.age === nextProps.age // Якщо true → не оновлюємо );

Тут функція areEqual(prevProps, nextProps) повертає:

  • true -> не оновлювати (аналог shouldComponentUpdate = false);
  • false -> оновлювати (аналог shouldComponentUpdate = true).

Пряма відповідність логіки

Що робитьКласовий варіантФункціональний варіант
Перевіряє, чи змінилися propsshouldComponentUpdate()React.memo()
Поверхневе порівняння за замовчуваннямНі (тільки через PureComponent)Так, вбудоване в React.memo()
Кастомна логіка порівнянняshouldComponentUpdate(nextProps, nextState)(prevProps, nextProps) => boolean
Пропускає ререндерreturn falseareEqual() → true

Приклад: еквівалентний код

Класовий компонент:

javascript
class Button extends React.Component { shouldComponentUpdate(nextProps) { return nextProps.label !== this.props.label; } render() { console.log('render'); return <button>{this.props.label}</button>; } }

Функціональний компонент:

javascript
const Button = React.memo( ({ label }) => { console.log('render'); return <button>{label}</button>; }, (prev, next) => prev.label === next.label );

Поведінка абсолютно однакова.


У чому різниця

ПараметрshouldComponentUpdate()React.memo()
Застосовується доКласових компонентівФункціональних компонентів
КонтрольВсередині компонентаЗзовні, при обгортанні
Порівняння stateТак (через nextState)Ні (лише props)
Можна перевизначитиТакТак (через areEqual)
За замовчуванням поверхневе порівнянняНі (потрібен PureComponent)Так
Де писатиВсередині класуЗзовні: React.memo(Component)

Приклад з оптимізацією

Без оптимізації:

javascript
function Parent({ user }) { return <Child user={user} />; } function Child({ user }) { console.log('render'); return <div>{user.name}</div>; }

Щоразу при новому об'єкті user -> Child перерендерюється. З React.memo():

javascript
const Child = React.memo(({ user }) => { console.log('render'); return <div>{user.name}</div>; });

Тепер React порівняє старий і новий user -> якщо посилання те саме, Child не оновиться.


Підсумок

React.memo()shouldComponentUpdate()

  • обидва потрібні, щоб запобігати зайвим ререндерам, якщо вхідні дані (props) не змінилися.
Спільна цільПоведінка
Підвищення продуктивностіПропуск ререндеру, якщо дані не змінилися
Поверхневе порівняння за замовчуваннямЛише у React.memo() і PureComponent
Гнучкість через кастомне порівнянняЄ в обох

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.