Що відбувається при оновленні компонента?
Що таке "оновлення" компонента
Оновлення (update) - це стадія життєвого циклу, при якій React повторно викликає компонент, щоб оновити його віртуальне представлення (Virtual DOM) і синхронізувати зміни з реальним DOM.
Що запускає оновлення
Компонент перемальовується, коли:
| Причина | Приклад |
|---|---|
Змінився стан (state) | setCount(count + 1) |
Прийшли нові пропси (props) | Батько передав нові дані |
| Батьківський компонент сам перерендерився | Навіть якщо пропси не змінилися |
Контекст (useContext) оновився | Змінилося значення провайдера |
Етапи оновлення покроково
1. Зміна даних
React отримує сигнал про те, що дані змінилися:
setCount(count + 1);Це не викликає оновлення одразу. React поміщає оновлення в чергу (batch) і вирішує, коли перерендерити компонент (особливо в React 18 із concurrent rendering).
2. Повторний виклик функції-компонента
React повторно викликає компонент (як звичайну функцію), щоб обчислити, який JSX він тепер повинен відрендерити.
function Counter() {
console.log("Рендер");
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Лічильник: {count}</button>;
}Кожен виклик компонента = новий "рендер".
3. Порівняння Virtual DOM (diffing)
React порівнює нове віртуальне дерево (результат нового JSX) з попереднім деревом.
- Якщо елементи відрізняються -> React змінює тільки ті частини DOM, що змінилися.
- Якщо вони однакові -> DOM не чіпається.
Це робить оновлення швидкими і точковими, без повної перемальовки сторінки.
4. Оновлення реального DOM
React застосовує тільки необхідні зміни до браузерного DOM.
Наприклад: якщо змінився тільки текст у кнопці - React замінить тільки текст, а не перестворить усю кнопку.
5. Виконання ефектів (useEffect, useLayoutEffect)
Після того як DOM оновлений, React викликає ефекти, у яких змінилися залежності.
useEffect(() => {
console.log("Оновлення: count змінився");
}, [count]);Якщо count змінився, ефект виконається знову.
Перед цим React викличе cleanup-функцію з попереднього ефекту.
Приклад: повний цикл оновлення
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Монтування");
return () => console.log("Демонтування");
}, []);
useEffect(() => {
console.log("Оновлення: count =", count);
return () => console.log("Очищення перед наступним ефектом");
}, [count]);
return (
<button onClick={() => setCount(c => c + 1)}>
Лічильник: {count}
</button>
);
}Що станеться:
Монтування
Оновлення: count = 0 ← перший запуск ефекту
(натиснули кнопку)
Очищення перед наступним ефектом
Оновлення: count = 1
(натиснули кнопку)
Очищення перед наступним ефектом
Оновлення: count = 2Різниця між монтуванням і оновленням
| Поведінка | Монтування | Оновлення |
|---|---|---|
| Чи викликається компонент | Так, вперше | Так, повторно |
| Чи створюється DOM | Повністю | Тільки зміни |
useEffect(() => {...}, []) | Спрацьовує | Не спрацьовує |
useEffect(() => {...}, [deps]) | Спрацьовує після монтування | При зміні залежностей |
cleanup у useEffect | Немає | Перед новим викликом ефекту |
Що зазвичай роблять при оновленні
| Завдання | Приклад |
|---|---|
| Реагувати на зміну даних | useEffect(() => {...}, [value]) |
| Синхронізувати DOM з новим станом | Застосовувати анімації, прокрутку |
| Оновлювати підписки | Спершу відписатися, потім підписатися знову |
| Перераховувати похідні значення | useMemo |
| Оптимізувати перерендери | React.memo, useCallback |
Аналоги в класових компонентах
| Етап | Класовий метод | Функціональний аналог |
|---|---|---|
| Після оновлення | componentDidUpdate(prevProps, prevState) | useEffect(() => {...}, [deps]) |
| Перед оновленням (рідко використовується) | shouldComponentUpdate() | React.memo / useMemo / useCallback |
Важливо пам'ятати
| Особливість | Пояснення |
|---|---|
| Функція-компонент викликається заново при кожному оновленні | Але стан (useState) зберігається між рендерами |
| React сам оптимізує оновлення DOM | Змінює тільки те, що потрібно |
| Не можна напряму змінювати DOM у тілі функції | Тільки в ефектах (useEffect, useLayoutEffect) |
useEffect виконується після оновлення DOM (асинхронно) | UI спершу оновиться, потім виконається ефект |
useLayoutEffect виконується до відмальовування екрана | Для синхронізації розмірів або положення елементів |
Підсумок
| Етап | Що робить React | Що робить розробник |
|---|---|---|
| 1. Зміна даних | Отримує новий state або props | Викликає setState / setCount |
| 2. Рендер | Заново викликає компонент | Повертає новий JSX |
| 3. Diff | Порівнює старий і новий Virtual DOM | Нічого не робить - React сам |
| 4. Commit | Оновлює реальний DOM | Можна реагувати в useEffect |
| 5. Ефекти | Запускає хуки, де змінилися залежності | Виконує побічні дії |
Головна ідея:
При оновленні React заново викликає компонент, перестворює Virtual DOM, порівнює його з попереднім, оновлює тільки потрібні частини DOM і запускає ефекти, у яких змінилися залежності.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.