{wcademy}

React: основы рендеринга

October 04, 2020

Введение в рендеринг

Думаю, все представляют себе, что реакт-приложение представляет собой некое дерево компонентов, так же как и в браузере отображается дерево html-объектов. Вот такое: дерево компонентов Рендеринг - это процесс, когда Реакт пробегается по дереву компонентов и просит каждый описать свою структуру в соответствии с комбинацией пропсов и стейта. Вот это «описать свою структуру» — вызов метода render (для компонентов-классов) или самого́ компонента (для функциональных). Всё это превращается в обычные js объекты с помощью React.createElement и сохраняется для дальнейшего использования.

Вот этот вывод называется виртуальным DOMом. Это почти что настоящий DOM (объектная модель документа, которую браузер создаёт в памяти компьютера на основании html-файла, wiki), и мы даже могли бы просто заменить всю страницу им, но дёргать браузер — долго. Поэтому Реакт сравнивает (причём ну очень эффективно) виртуальный дом с текущим состоянием страницы и составляет список изменений, которые нужно сделать, чтобы актуализировать текущее состояние страницы в соответствии с построенным виртуальным DOM. Этот процесс называется reconciliation (на хабре часто переводят как «сверка», в частичном переводе оф. доков переводят как «согласование», давайте не страдать фигней, а использовать английские термины).

Рендеринг и фиксация

Процесс разбит на две логические части:

  • Фаза рендеринга — рендеринг компонентов, нахождение изменений
  • Фаза фиксации изменений — применение изменений к непосредственно DOMу

После фазы фиксации Реакт вызовет методы жизненного цикла componentDidMount и componentDidUpdateдля компонентов-классов, и с небольшим таймаутом, хуки useEffect.

Два ключевых вывода на данный момент:

  • Рендеринг не то же самое, что и обновление браузерного DOM
  • Компонент может перерендериваться раз за разом, без видимых изменений

Причины перерендеринга

После первоначального рендеринга страницы, перерендеринг может быть вызван следующими причинами:

  • Для компонентов-классов: this.setState и this.forceUpdate
  • Для функциональных компонентов: вызов сеттеров хуков useState или useReducer
  • повторный вызов ReactDOM.render() для корневого компонента

Поведение при рендеринге

По умолчанию Реакт рекурсивно отрендерит все дочерние компоненты когда рендерится родительский. Это значит, что неважно, изменились ли пропсы или нет — неважно, в любом случае все дочерние компоненты будут перерендерены.

Другими словами, если вызвать setState для корневого компонента (даже если ничто другое не поменяется, это вызовет перерендеринг каждого компонента приложения. Благо, если все компоненты вернут тот же результат, что и в прошлый раз, реальный DOM перерисовывать не придётся. Но вызов рендера для каждого компонента и сравнение не бесплатны, мы платим за это процессорным временем и тормозами, если это происходит слишком часто.

🚀  Если узнал из статьи что-то полезное, ставь лайк и подписывайся на наш канал в Телеграм или группу ВК. Обсудить статью можно в нашем уютном чатике 😏

© 2019 - 2022, {wcademy}