От автора: часто неспособность отладить какую-то ошибку проистекает из того, что вы не понимаете определенную основополагающую концепцию. Аналогично вы можете не понимать более продвинутые концепции, потому что вам не хватает знаний об определенных базовых принципах.
В этой статье я надеюсь объяснить то, что я считаю наиболее важными основополагающими принципами React, которые вам нужно понять. Эти React основы не являются чисто техническими. Есть много других статей, в которые рассматриваются такие вещи: как свойство, состояние, контекст, setState и т. д.
В этой статье я сосредоточусь на определенных концептуальных понятиях, которые составляют основу большинства технических вещей в React. Готовы?
Как работает React под капотом
Одна из первых вещей, которые каждый узнает в React — это то, как создавать компоненты. Я уверен, вы тоже это изучали. Например:
1 2 3 4 5 6 7 8 9 10 11 |
// функциональный компонент function MyComponent() { return <div> My Functional Component </div> } // класс на основе компонента class MyComponent extends React.Component { render() { return <div> My Class Component </div> } } |
Большинство компонентов, которые вы пишете, возвращают некоторые элементы:
1 2 3 4 5 6 7 8 9 |
function MyComponent() { return <span> My Functional Component </span> //элемент span } class MyComponent extends React.Component { render() { return <div> My Class Component </div> // элемент div } } |
Под капотом большинство компонентов возвращают дерево элементов.
Компоненты, когда они оцениваются внутри, часто возвращают дерево элементов.
Вы также должны помнить, что компоненты похожи на функции, возвращающие значения на основе их значений props и state.
Компоненты похожи на функции с параметрами «props» и «state».
Следовательно, всякий раз, когда изменяется значение props или state компонента, отображается новое дерево элементов.
Если значения props или state изменяются, дерево элементов повторно отображается. В результате получается новое дерево.
Если компонент является компонентом класса, для возврата дерева элементов вызывается функция render.
1 2 3 4 5 6 |
class MyComponent extends React.Component { render() { //эта функция вызывается, чтобы вернуть дерево элементов } } |
Если компонент является функциональным компонентом, его возвращаемое значение дает дерево элементов.
1 2 3 4 5 6 |
function MyComponent() { // возвращаемое значение дает дерево элементов return <div> </div> } |
Почему это важно? Рассмотрим компонент, <MyComponent />, который принимает prop, как показано ниже:
1 |
<MyComponent name='Ohans'/> |
Когда этот компонент визуализируется, возвращается дерево элементов.
Дерево элементов, возвращенных из рендеринга MyComponent
Что происходит при изменении значения name?
1 |
<MyComponent name='Ohans'/> |
Ну, возвращается новое дерево элементов!
Новое дерево элементов, возвращаемое из рендеринга MyComponent с различными свойствами
Хорошо. Теперь, React имеет два разных дерева — первоначальное и текущее дерево элементов. На этом этапе React сравнивает оба дерева, чтобы найти, что именно изменилось.
Два разных дерева. Что именно изменилось в обоих деревьях?
В большинстве случаев все дерево не меняется. Просто некоторые обновления тут и там. После сравнения этих двух деревьев элементов, фактическая DOM обновляется с учетом изменением нового дерева элементов. Просто, да?
Этот процесс сравнения двух деревьев для изменений называется «согласованием». Хотя это технический процесс, но этот концептуальный обзор отлично подходит для понимания того, что происходит под капотом.
React обновляет только то, что необходимо. Правильно?
Когда вы начинаете работу с React, все рассказывают, насколько удивительным он является — особенно, как он просто обновляет важную часть DOM.
Из документации React: Инспектор DOM, показывающий подробные обновления.
Это полностью верно? Да, это так. Однако, прежде чем React получит обновление DOM, помните, что под капотом он сначала построит дерево элементов для различных компонентов и выполнит «сравнение» перед обновлением DOM. Другими словами, он сравнивает изменения между предыдущими и текущими деревьями элементов.
Причина, по которой я повторно напоминаю это, заключается в том, что если вы новичок в React, вы можете не обратить внимание на нюансы производительности, связанные с вашим приложением, потому что думаете, что React просто обновляет DOM тем, что необходимо. Хотя это верно, производительность большинства приложений React начинается с процесса до обновления DOM!
Расточительный рендеринг или визуальное обновление
Независимо от того, насколько он незначителен, рендеринг дерева элементов компонентов занимает некоторое время (неважно, сколько мгновений). Время рендеринга увеличивается по мере увеличения дерева компонентов.
Следствием этого является то, что вы не хотите, чтобы React повторно отображал дерево компонентов, если это НЕ важно. Позвольте мне показать вам простой пример. Рассмотрим приложение со структурой компонентов, как показано ниже:
Приложение с родительским компонентом A и дочерними компонентами B, C и D.
Общий компонент контейнера A получает определенное свойство. Однако единственной причиной этого является необходимость передачи свойства до компонента D.
Родительский компонент A получает некоторые свойства и передает их дочернему компоненту D
Теперь, когда изменяется значение prop в A, все дочерние элементы A повторно отображаются для вычисления нового дерева элементов.
Когда родительский компонент получает новые свойства, каждый дочерний элемент повторно отображается и возвращается новое дерево
Подразумевается, что компоненты B и C также повторно отображаются, даже если они не изменились вообще! Они не получили никаких новых свойств! Этот ненужный повторный рендеринг — это то, что называется «расточительным» рендерингом. В этом примере B и C не нужно повторно отображать, но React этого не знает. Теперь рассмотрите приложение ниже:
Cardey в действии 🙂
Я называю это приложение Cardey. Когда я нажимаю кнопку, чтобы изменить профессию пользователя, я могу выбрать выделение обновлений для DOM, как показано ниже:
Включите визуальные обновления (Paint Flashing) через Chrome Devtools
И теперь я вижу, что было обновлено в DOM. Это представление визуальных обновлений для DOM. Обратите внимание на зеленую вспышку вокруг текста «I am a Librarian». Это здорово, но я обеспокоен первоначальным рендерингом React дерева компонентов. Таким образом, я мог бы также выбрать и его проверку.
Включите переключатель подсветки обновлений в React Devtools
После этого я вижу, какие компоненты действительно повторно отображаются, когда я нажимаю эту кнопку.
Обратите внимание на зеленую вспышку вокруг карточки пользователя
Вы видите, чем отличаются визуальные обновления DOM и обновления рендеринга React? Большая карточка пользователя была повторно отображена, но при этом обновилась только небольшая область текста.
Заключение
Я считаю, что теперь у вас есть более интуитивное понимание того, что происходит под капотом в компонентах React.
На самом деле, гораздо больше, чем я рассмотрел здесь. Однако это неплохо для старта. Теперь вы можете попробовать создать отличные приложения!
Автор: Ohans Emmanuel
Источник: //medium.freecodecamp.org/
Редакция: Команда webformyself.