Spec-Zone.ru › React

Отрисовка и фиксация

Прежде чем ваши компоненты будут отображены на экране, их необходимо отрисовать React. Понимание этапов этого процесса поможет вам разобраться в том, как выполняется ваш код, и объяснить его поведение.

Вы узнаете

  • Что означает отрисовка в React
  • Когда и почему React отрисовывает компонент
  • Этапы отображения компонента на экране
  • Почему отрисовка не всегда приводит к обновлению DOM

Представьте, что ваши компоненты — это повара на кухне, собирающие вкусные блюда из ингредиентов. В этом сценарии React — это официант, который принимает заказы от клиентов и приносит им их. Этот процесс получения и предоставления пользовательского интерфейса состоит из трех этапов:

  1. Вызов отрисовки (передача заказа клиента на кухню)
  2. Отрисовка компонента (приготовление заказа на кухне)
  3. Фиксация в DOM (размещение заказа на столе)
  1. React as a server in a restaurant, fetching orders from the users and delivering them to the Component Kitchen.
    Вызов
  2. The Card Chef gives React a fresh Card component.
    Отрисовка
  3. React delivers the Card to the user at their table.
    Фиксация

Иллюстрация предоставлена Рэйчел Ли Наборс

Шаг 1: Вызов отрисовки

Существует две причины для отрисовки компонента:

  1. Это первичная отрисовка компонента.
  2. Состояние компонента (или одного из его предков) было обновлено.

Первичная отрисовка

При запуске приложения необходимо вызвать первичную отрисовку. Фреймворки и песочницы иногда скрывают этот код, но он выполняется путем вызова 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. Обновление состояния компонента автоматически добавляет в очередь отрисовку. (Вы можете представить это как ситуацию, когда гость в ресторане заказывает чай, десерт и многое другое после первого заказа, в зависимости от степени жажды или голода.)

  1. React as a server in a restaurant, serving a Card UI to the user, represented as a patron with a cursor for their head. They patron expresses they want a pink card, not a black one!
    Обновление состояния…
  2. React returns to the Component Kitchen and tells the Card Chef they need a pink Card.
    …вызывает…
  3. The Card Chef gives React the pink Card.
    …отрисовку!

Иллюстрация предоставлена Рэйчел Ли Наборс

Шаг 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 рассчитает, какие из их свойств, если таковые имеются, изменились с момента предыдущей отрисовки. Он не будет ничего с этим делать до следующего шага — этапа фиксации.

Опасность

Отрисовка должна всегда быть чистым вычислением:

  • Одинаковые входные данные, одинаковый выход. При одинаковых входных данных компонент должен всегда возвращать одинаковый JSX. (Если кто-то заказывает салат с помидорами, он не должен получить салат с луком!)
  • Заниматься своими делами. Он не должен изменять какие-либо объекты или переменные, существовавшие до отрисовки. (Один заказ не должен менять заказ другого человека.)

В противном случае вы можете столкнуться с непонятными ошибками и непредсказуемым поведением по мере роста сложности вашего кода. При разработке в «Жестком режиме» React вызывает функцию каждого компонента дважды, что может помочь выявить ошибки, вызванные нечистыми функциями.

Подробное изучение

Оптимизация производительности

По умолчанию отрисовка всех компонентов, вложенных в обновленный компонент, не является оптимальной с точки зрения производительности, если обновленный компонент находится очень высоко в дереве. Если у вас возникнут проблемы с производительностью, существует несколько способов решения этой проблемы, описанных в разделе Производительность. Не оптимизируйте преждевременно!

Шаг 3: React фиксирует изменения в DOM

После отрисовки (вызова) ваших компонентов React внесет изменения в DOM.

  • При первоначальной отрисовке React использует API DOM appendChild(), чтобы поместить все созданные узлы 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!

Заключение: Отрисовка браузера

После завершения отрисовки и обновления DOM React браузер перерисует экран. Хотя этот процесс известен как «отрисовка браузера», мы будем называть его «перерисовкой», чтобы избежать путаницы в документации.

A browser painting 'still life with card element'.

Иллюстрация предоставлена Рэйчел Ли Наборс

Резюме

  • Любое обновление экрана в приложении React происходит в три этапа:
    1. Вызов
    2. Отрисовка
    3. Фиксация
  • Вы можете использовать режим строгой проверки, чтобы найти ошибки в своих компонентах
  • React не изменяет DOM, если результат отрисовки такой же, как и в прошлый раз

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/learn/render-and-commit

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API