Рендер і фіксація
Перш ніж ваші компоненти відобразяться на екрані, вони мають бути відрендереними за допомогою React. Розуміння кроків цього процесу допоможе вам подумати про те, як виконується ваш код, і пояснити його поведінку.
You will learn
- Що таке рендеринг в React
- Коли і чому React рендерить компонент
- Кроки виведення компоненту на екран
- Чому рендеринг не завжди призводить до оновлення DOM
Уявіть, що ваші компоненти - це кухарі на кухні, які збирають смачні страви з інгредієнтів. У цьому сценарії React - це офіціант, який приймає запити від клієнтів і приносить їм замовлення. Цей процес запиту та обслуговування UI складається з трьох кроків:
- Запуск рендеру (доставка замовлення гостя на кухню)
- Рендеринг компонента (підготовка замовлення на кухні)
- Фіксація у DOM (розміщення замовлення на столі)
Illustrated by Rachel Lee Nabors
Крок 1: Запуск рендерингу
Існує дві причини для рендерингу компонента:
- Це початковий рендер компонента.
- Було оновлено стан компонента (або одного з його предків).
Початковий
Під час запуску програми вам потрібно запустити початковий рендеринг. Фреймворки та пісочниці іноді приховують цей код, але це робиться шляхом виклику createRoot
з цільового DOM-вузла, і потім викликом його методу render
з вашим компонентом:
import Image from './Image.js'; import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')) root.render(<Image />);
Спробуйте закоментувати виклик root.render()
і побачите, що компонент зникне!
Повторний рендеринг при оновленні стану
Після першого рендерингу компонента ви можете викликати подальші рендеринги, оновивши його стан за допомогою функціїset
function. Оновлення стану вашого компонента автоматично ставить рендеринг у чергу. (Ви можете уявити це як відвідувача ресторану, який після першого замовлення замовляє чай, десерт та інші речі, залежно від стану спраги чи голоду).
Illustrated by Rachel Lee Nabors
Крок 2: React рендерить ваші компоненти
Після того, як ви запускаєте рендер, React викликає ваші компоненти, щоб з’ясувати, що виводити на екраню “Рендеринг” - це виклик React’ом ваших компонентів.
- При початковому рендерингу, React викличе кореневий компонент.
- Для наступних рендерів, React буде викликати компонент функції, оновлення стану якого викликало рендер.
Цей процес є рекурсивним: якщо оновлений компонент повертає якийсь інший компонент, React буде рендерити цей компонент наступним, і якщо цей компонент також щось повертає, він буде рендерити цей компонент наступним і так далі. Процес продовжуватиметься доти, доки не залишиться більше вкладених компонентів і React точно знатиме, що саме має бути відображено на екрані.
У наступному прикладі React викличе Gallery()
і Image()
кілька разів:
export default function Gallery() { return ( <section> <h1>Inspiring Sculptures</h1> <Image /> <Image /> <Image /> </section> ); } function Image() { return ( <img src="https://i.imgur.com/ZF6s192.jpg" alt="'Floralis Genérica' by Eduardo Catalano: a gigantic metallic flower sculpture with reflective petals" /> ); }
- Під час початкового рендерингу, React створить вузли DOM для
<section>
,<h1>
, і трьох<img>
тегів. - Під час ре-рендерингу, React вирахує, які властивості цих елементів, якщо такі були, змінилися з моменту попереднього рендерингу. Він нічого не буде робити з цією інформацією до наступного кроку, фази фіксації.
Deep Dive
Поведінка за замовчуванням, яка полягає у рендерингу усіх компонентів, вкладених у оновлений компонент, не є оптимальною для продуктивності, якщо оновлений компонент знаходиться дуже високо у дереві. Якщо ви зіткнулися з проблемою продуктивності, є кілька варіантів її вирішення, описаних в розділі Продуктивність. Не оптимізуйте передчасно!
Крок 3: React фіксує зміни в DOM
Після рендерингу (виклику) ваших компонентів, React змінюватиме DOM.
- Для початкового рендерингу, React використовуватиме
appendChild()
DOM API, щоб вивести на екран усі створені ним вузли DOM. - Для ре-рендерингів, React застосовуватиме мінімально необхідні операції (обчислені під час рендерингу!) щоб зробити DOM відповідним останньому результату рендерингу.
React змінює вузли DOM тільки якщо є різниця між рендерами. Наприклад, ось компонент, який ре-рендериться щосекунди з різними пропсами, переданими від батька. Зверніть увагу, що ви можете додати текст у <input>
, оновивши його value
, але текст не зникає, коли компонент ре-рендериться:
export default function Clock({ time }) { return ( <> <h1>{time}</h1> <input /> </> ); }
Це працює, тому що на останньому кроці React оновлює лише вміст <h1>
з новим time
. Він бачить, що <input>
з’являється в JSX в тому ж місці, що і минулого разу, тому React не чіпає <input>
— або його value
!
Епілог: Малювання браузера
Після того, як рендеринг завершено і React оновив DOM, браузер перемалює екран. Хоча цей процес відомий як “рендеринг браузера”, ми будемо називати його “малюванням”, щоб уникнути плутанини в документації.
Illustrated by Rachel Lee Nabors