Рендер и фиксация
Прежде чем ваши компоненты будут отображены на экране, React должен их отрендерить. Понимание шагов этого процесса поможет вам задуматься о том, как выполняется ваш код, и объяснить его поведение.
Вы узнаете
- Что означает рендеринг в React
- Когда и почему React рендерит компонент
- Шаги, связанные с отображением компонента на экране
- Почему рендеринг не всегда приводит к обновлению DOM
Представьте, что ваши компоненты — это повара на кухне, собирающие вкусные блюда из ингредиентов. В этом сценарии React — это официант, который принимает заказы от клиентов и приносит им их блюда. Этот процесс запроса и подачи пользовательского интерфейса состоит из трёх шагов:
- Инициированиерендера (передача заказа гостя на кухню)
- Рендерингкомпонента (приготовление заказа на кухне)
- Фиксацияв DOM (размещение заказа на столе)
Инициирование
Рендеринг
Фиксация
Иллюстрации:Rachel Lee Nabors
Шаг 1: Инициирование рендера
Существует две причины для рендеринга компонента:
- Это первоначальный рендер компонента.
- Состояние компонента (или одного из его предков)было обновлено.
Первоначальный рендер
При запуске вашего приложения необходимо инициировать первоначальный рендер. Фреймворки и песочницы иногда скрывают этот код, но он выполняется путём вызоваcreateRootс целевым узлом DOM, а затем вызова его методаrenderс вашим компонентом:
Попробуйте закомментировать вызовroot.render()и увидите, как компонент исчезнет!
Повторные рендеры при обновлении состояния
После того как компонент был первоначально отрендерен, вы можете инициировать дальнейшие рендеры, обновляя его состояние с помощьюфункции set.Обновление состояния вашего компонента автоматически ставит рендер в очередь. (Вы можете представить это как посетителя ресторана, который заказывает чай, десерт и всё что угодно после своего первого заказа, в зависимости от состояния его жажды или голода.)
Обновление состояния...
...инициирует...
...рендер!
Иллюстрации:Rachel Lee Nabors
Шаг 2: React рендерит ваши компоненты
После того как вы инициировали рендер, React вызывает ваши компоненты, чтобы выяснить, что отображать на экране.«Рендеринг» — это вызов React'ом ваших компонентов.
- При первоначальном рендереReact вызовет корневой компонент.
- При последующих рендерахReact вызовет функциональный компонент, чьё обновление состояния инициировало рендер.
Этот процесс рекурсивный: если обновлённый компонент возвращает какой-либо другой компонент, React отрендеритэтоткомпонент следующим, и если этот компонент тоже что-то возвращает, он отрендеритэтоткомпонент следующим, и так далее. Процесс будет продолжаться, пока не останется больше вложенных компонентов и React не узнает точно, что должно быть отображено на экране.
В следующем примере React вызоветGallery() и Image()несколько раз:
- При первоначальном рендерингеReactсоздаст DOM-узлыдля
<section>,<h1>и трёх тегов<img>. - При повторном рендерингеReact вычислит, какие из их свойств, если таковые имеются, изменились с момента предыдущего рендеринга. Он не будет ничего делать с этой информацией до следующего шага — фазы фиксации.
Подводный камень
Рендеринг всегда должен бытьчистым вычислением:
- Одинаковые входные данные — одинаковый результат.При одинаковых входных данных компонент всегда должен возвращать одинаковый JSX. (Когда кто-то заказывает салат с помидорами, он не должен получить салат с луком!)
- Он занимается своим делом.Он не должен изменять никакие объекты или переменные, существовавшие до рендеринга. (Один заказ не должен изменять чужой заказ.)
В противном случае по мере усложнения кодовой базы могут возникать запутанные ошибки и непредсказуемое поведение. При разработке в «Строгом режиме» React вызывает функцию каждого компонента дважды, что может помочь выявить ошибки, вызванные нечистыми функциями.
Шаг 3: React фиксирует изменения в DOM
После рендеринга (вызова) ваших компонентов React изменит DOM.
- При первоначальном рендерингеReact использует DOM APIappendChild(), чтобы разместить на экране все созданные DOM-узлы.
- При повторных рендерингахReact применит минимально необходимые операции (вычисленные во время рендеринга!), чтобы привести DOM в соответствие с последним результатом рендеринга.
React изменяет DOM-узлы только в случае различий между рендерами.Например, вот компонент, который перерисовывается с разными пропсами, передаваемыми от родителя, каждую секунду. Обратите внимание, что вы можете добавить текст в<input>, обновив егоvalue, но текст не исчезает при повторном рендеринге компонента:
Это работает, потому что на последнем шаге React обновляет только содержимое<h1>новым значениемtime. Он видит, что<input>появляется в JSX в том же месте, что и в прошлый раз, поэтому React не трогает<input>— или егоvalue!
Эпилог: Отрисовка браузером
После завершения рендеринга и обновления DOM React'ом браузер перерисует экран. Хотя этот процесс известен как «рендеринг браузера», мы будем называть его «отрисовкой», чтобы избежать путаницы в документации.

Иллюстрация:Рэйчел Ли Наборс
Итоги
- Любое обновление экрана в React-приложении происходит в три этапа:
- Триггер
- Рендер
- Фиксация
- Вы можете использовать Строгий режим для поиска ошибок в ваших компонентах
- React не трогает DOM, если результат рендеринга совпадает с предыдущим
