Представление UI в виде дерева
Ваше приложение React формируется с множеством вложенных друг в друга компонентов. Как же React отслеживает структуру компонентов вашего приложения?
React, как и многие другие библиотеки, моделирует UI в виде дерева. Представив ваше приложение в виде дерева, вы сможете лучше понять взаимосвязь между компонентами, а так же это поможет вам в отладке будущих концепций, таких как: производительность и управление состоянием.
You will learn
- Как React «видит» структуру компонентов
- Что такое дерево рендеринга и в чем его польза
- Что такое дерево зависимостей модулей и в чем его польза
UI в виде дерева
Дерево — это модель отношений между элементами, и UI часто использует эту структуру. Например, браузеры используют тот же подход для построения HTML (DOM) и CSS (CSSOM). Мобильные платформы так же используют структуру дерева для своей иерархии.
React, так же как браузеры и мобильные платформы, использует структуру дерева для управления и построения связи между компонентами. Эти деревья являются полезным инструментом и помогут вам понять как данные проходят через приложение React, как оптимизировать рендеринг и размер приложения.
Дерево рендеринга
Основной особенностью компонентов считается возможность составлять одни компоненты из других. Когда мы вкладываем компоненты, у нас есть концепция родительских и дочерних компонентов, где каждый родительский компонент сам может быть дочерним по отношению к другому.
Когда мы рендерим React-приложение, мы можем смоделировать эти связи в виде дерева, известного как дерево рендеринга.
Вот пример приложения React, которое отображает вдохновляющие цитаты.
import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; export default function App() { return ( <> <FancyText title text="Get Inspired App" /> <InspirationGenerator> <Copyright year={2004} /> </InspirationGenerator> </> ); }
Из примера приложения мы можем построить приведенное выше дерево рендеринга.
Дерево состоит из узлов, каждый из них представляет компонент. App
, FancyText
, Copyright
и многие другие — это узлы нашего дерева.
Корневой узел в дереве рендеринга React является корневым компонентом приложения. В нашем случае корневой компонент предстовлен App
, и React рендерит его первым. Каждое ответление в дереве идёт от родительского компонента к дочернему.
Deep Dive
Возможно, вы уже заметили, что в приведенном выше дереве рендеринга нет упоминания о HTML-тегах, которые отображает каждый компонент. Это происходит потому, что дерево рендеринга состоит только из компонентов React.
Как UI-фреймворк, React является платформонезависимым. В документации мы демонстрируем примеры рендеринга в web, где в качестве примитивов UI используется разметка HTML. Но приложение React так же может запускаться на мобильных или десктоп платформах, которые используют другие UI-примитивы, такие как: UIView или FrameworkElement.
Но примитивы на этих платформах не являются частью React. Его дерево может давать представление о вашем приложении независимо от того, на какой платформе запускается ваше приложение.
Дерево рендеринга представляет собой одиночный рендеринг приложения React. При условном рендеринге родительский компонент может рендерить разные дочерние компоненты в зависимости от переданных данных.
Мы можем обновить наше приложение, чтобы оно по условию отоброжало либо вдохновляющую цитату, либо цвет.
import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; export default function App() { return ( <> <FancyText title text="Get Inspired App" /> <InspirationGenerator> <Copyright year={2004} /> </InspirationGenerator> </> ); }
В данном случае, мы рендерим <FancyText>
или <Color>
в зависимости от inspiration.type
. При каждом рендеринге дерево может быть разным.
Хотя деревья рендеринга могут различаться в зависимости от этапа рендеринга, обычно они полезны для определения того, что представляют собой компоненты верхнего уровня и конечные компоненты в приложении React. Компоненты верхнего уровня — это те, которые находятся ближе к корневому компоненту. Они влияют на производительность рендеринга всех дочерних компонентов, и часто содержат наибольшую сложность. Конечные компоненты находятся в нижней части дерева. Они не имеют дочерних компонентов и часто рендерятся повторно.
Определение того, к какой категории относится компонент поможет вам лучше понять поток данных и улучшнить производительность вашего приложения.
Дерево зависимостей модулей
Еще одна связь в приложении React, которую можно смоделировать с помощью дерева, — это зависимости модулей приложения. Разбивая компоненты и логику на отдельные файлы, мы создаем JS-модули, в которые можно экспортировать компоненты, функции или константы.
Каждый узел в дереве зависимостей модулей является модулем, а каждую ветвь представляет import
.
Если мы возьмем предыдущее приложение с вдохновляющими цитатами, мы сможем построить дерево зависимостей модулей.
Корневым узлом дерева является корневой модуль, он же файл точки входа. Часто это модуль, содержащий корневой компонент.
Сравнив с деревом рендеринга, мы увидим схожие структуры и некоторые заметные различия:
- Узлы, составляющие дерево, представляют собой модули, а не компоненты.
- Модули которые не являются компонентами, такие как
inspirations.js
, также представлены в этом дереве. А дерево рендеринга инкапсулирует только компоненты. Copyright.js
появляется подApp.js
. Но в дереве рендерингаCopyright
отображается как дочерний элементInspirationGenerator
. Это связано с тем, чтоInspiration Generator
принимает JSX в качестве дочерних пропсов, поэтому он отображаетCopyright
как дочерний компонент, но он не импортирует его.
Дерево зависимостей помогает определить какие модули необходимы для запуска вашего React приложения. При создании приложения для продакшена есть этап сборки, на котором весь необходимый JavaScript будет отправлен клиенту. На этом этапе сборщик пакетов использует дерево зависимостей для того, чтобы определить какие модули содержит проект.
По мере роста вашего приложения часто увеличивается и размер сборщика. При больших размерах требуется больше затрат для загрузки и запуска клиента, а так же это может задерживать прорисовку вашего UI. Понимание же дерева зависимостей вашего приложения может помочь в отладке и устранении этих проблем.
Recap
- Деревья — это распространенный способ показать отношения между сущностями. Они очень частно используются для построения UI.
- Деревья рендеринга представляют собой отношения между вложенными компонентами React в рамках одной отрисовки.
- С отрисоквой по условию, дерево рендеринга может меняться при разных запусках. В зависимости от пропсов, компоненты могут отображать разные дочерние компоненты.
- Деревья рендеринга помогают определить, что такое компоненты верхнего уровня и конечные компоненты. Компоненты верхнего уровня влияют на производительность отрисовки всех компонентов, находящихся под ними, а конечные компоненты часто перерисовываются повторно. Их выявление поможет вам для понимания и отладки производительности рендеринга.
- Дерево зависимостей — это зависимость модулей в приложении React.
- Деревья зависимостей пользуются инструментами сборки для объединения необходимого кода для отправки приложения.
- Деревья зависимостей полезны для отладки пакетов больших размеров, которые замедляют прорисовку и предоставляют возможности для оптимизации.