Какая последовательность render в React?
Рендеринг и производительность
Обновление в React проходит фиксированную последовательность: триггер → render-фаза → commit-фаза → эффекты.
Полный конвейер
Триггер. Первичный рендер (createRoot().render()) или обновление: сеттер state, dispatch, изменение контекста, подписка стора.
Render-фаза (чистые вычисления, прерываемая).
- React вызывает функции компонентов сверху вниз от «грязного» компонента: родитель → дети → глубже.
- Строится новое виртуальное дерево.
- Reconciliation: сравнение с прошлым деревом, вычисление минимальных изменений.
Commit-фаза (синхронная).
- Изменения применяются к реальному DOM.
- Отрабатывают cleanup'ы useLayoutEffect, затем сами useLayoutEffect — синхронно, до отрисовки.
- refs получают актуальные DOM-узлы.
Отрисовка браузера. Пользователь видит кадр.
Пассивные эффекты. Cleanup'ы useEffect прошлого цикла, затем новые useEffect.
Порядок внутри дерева
const Parent = () => {
console.log('render Parent'); // 1
useEffect(() => console.log('effect Parent')); // 4 (эффекты — снизу вверх!)
return <Child />;
};
const Child = () => {
console.log('render Child'); // 2
useEffect(() => console.log('effect Child')); // 3
return null;
};Рендер идёт сверху вниз (Parent → Child), а эффекты выполняются снизу вверх (Child → Parent) — дети «готовы» раньше родителей.
Нюанс конкурентности
С React 18 render-фаза может прерываться ради срочных обновлений и выполняться заново, поэтому она обязана быть чистой; commit всегда синхронный и цельный.
Коротко для собеседования
Последовательность: триггер → render (вызовы компонентов сверху вниз, дифф) → commit (правки DOM, useLayoutEffect) → отрисовка → useEffect. Рендер — сверху вниз, эффекты — снизу вверх (сначала дети). Render-фаза чистая и прерываемая, commit — синхронный.