Разница между компонентом React и элементом React
В чем разница между React Component и React Element? В документации упоминаются оба, но не вдаются подробности, некоторые методы требуют компонентов, другие элементы.
11 ответов
Элементы — это преобразователи.
React позволяет вам определять пользовательские интерфейсы как чистые функции, определенные в состоянии приложения. Это можно было бы реализовать, вычисляя весь пользовательский интерфейс при каждом изменении состояния, но это было бы дорого. Элементы — это вычислительные описания (преобразователи), и если они не меняются, и вы используете PureComponent , React не будет пересчитывать это поддерево.
Здесь задействованы три родственные вещи с собственными именами:
- Составные части
- Экземпляры компонента
- Элементы
Это немного удивительно, поскольку, если вы привыкли к другим инфраструктурам пользовательского интерфейса, вы можете ожидать, что будет только два типа вещей, примерно соответствующих классам (например, Widget ) и экземплярам (например, new Widget() ). ). В React это не так; Экземпляры компонентов отличаются от элементов, и между ними нет однозначной связи. Чтобы проиллюстрировать это, рассмотрим этот код:
В приведенном выше коде:
- MyComponent (сам класс) является компонентом
- element является элементом. Это не экземпляр MyComponent ; скорее, это просто описание создаваемого экземпляра компонента. Это объект со свойствами key , props , ref и type . Здесь key и ref — это null , props — пустой объект, а type — это MyComponent .
- экземпляр MyComponent создается (и, в приведенном выше примере, регистрирует себя из своего конструктора), когда element обрабатывается.
- another_element также является элементом и имеет свойства key , ref , props и type точно так же, как element , но на этот раз значение из type — это строка «div» .
Причины дизайна, по которым в React используются эти три разные концепции, подробно рассматриваются в сообщении блога команды React Компоненты, элементы и экземпляры React, который я рекомендую прочитать.
Наконец, следует отметить, что, хотя в официальных документах строго используется термин «компонент» для обозначения функции или класса и «экземпляр компонента» для обозначения экземпляра, другие источники не обязательно придерживаются этой терминологии; вы должны ожидать, что «компонент» используется (неправильно) для обозначения «экземпляр компонента» при чтении ответов Stack Overflow или обсуждений на GitHub.
Чтобы уточнить ответ, React Element не имеет никаких методов и ничего в прототипе. Это также делает их быстрыми.
«ReactElement — это легкое, неизменяемое виртуальное представление элемента DOM без сохранения состояния» — Глоссарий терминов React
Функция компонента реакции render() возвращает DOM-дерево реагирующих элементов за кулисами (кстати, это виртуальный DOM). Здесь задействована некоторая сложная логика сопоставления и сравнения, но в основном эти элементы React сопоставляются с элементами DOM.
Вы также можете создать элемент напрямую React.createElement(arg) , где arg может быть именем HTML-тега или классом компонента React.
Реагировать на элементы
Элемент React — это просто старый добрый JavaScript Object без собственных методов. Он имеет по существу четыре свойства:
- type , String , представляющий тег HTML или ссылку, относящуюся к компоненту React.
- key , String для уникальной идентификации элемента React.
- ref , ссылка для доступа либо к базовому узлу DOM, либо к экземпляру компонента React)
- props (свойства Object )
Элемент React не является экземпляром компонента React. Это просто упрощенное «описание» того, как должен выглядеть создаваемый экземпляр компонента React (или в зависимости от type HTML-тега).
Элемент React, описывающий компонент React, не знает, на каком узле DOM он в конечном итоге отображается — эта ассоциация абстрагирована и будет разрешена во время рендеринга.
Элементы React могут содержать дочерние элементы и, таким образом, способны формировать деревья элементов, которые представляют дерево Virtual DOM.
Компоненты React и экземпляры компонентов React
Пользовательский компонент React создается либо с помощью React.createClass , либо путем расширения React.Component (ES2015). Если создается экземпляр компонента React, он ожидает props Object и возвращает экземпляр, который называется экземпляром компонента React.
Компонент React может содержать состояние и иметь доступ к методам жизненного цикла React. Он должен иметь как минимум метод render , который при вызове возвращает React Element(-tree). Обратите внимание, что вы никогда не создаете экземпляры компонентов React самостоятельно, а позволяете React создать их за вас.
Элементы React против компонентов React
Реагировать на элементы
- Элемент React — это то, что возвращается из компонентов. Это объект, который виртуально описывает узлы DOM, которые представляет компонент.
- В функциональном компоненте этот элемент является объектом, который возвращает функция.
- С компонентом класса элемент является объектом, который возвращает функция рендеринга компонента. р
- Элементы React — это не то, что мы видим в браузере. Это всего лишь объекты в памяти, и мы ничего не можем в них изменить.
- Элементы React могут иметь другие свойства type , отличные от собственных элементов HTML.
- Элемент реакции описывает то, что мы хотим видеть на экране.
- Элемент React — это объектное представление узла DOM.
_ Здесь важно провести это различие, потому что элемент — это не то, что мы видим на экране, а то, что визуализируется в виде объекта.
React хорош с этим в следующих отношениях:
- React может создавать и уничтожать эти элементы без особых затрат. Объекты JS легкие и недорогие.
- React может сравнить объект с предыдущим представлением объекта, чтобы увидеть, что изменилось.
- React может обновлять фактический DOM именно там, где произошли обнаруженные изменения. Это имеет некоторые преимущества в производительности.
- Имя тега (например, div, span и т. д.)
- Любые атрибуты, которые мы хотим, чтобы элемент имел
- Содержимое дочерних элементов элемента (например, текст, который читается как Login )
Как правило, React преподается с использованием подхода «сначала компоненты», однако понимание «сначала элементы» обеспечивает плавный переход к компонентам.
Реагировать Компоненты
Компонент — это функция или класс, который необязательно принимает ввод и возвращает элемент React.
Компонент React — это шаблон. План. Глобальное определение. Это может быть либо функция, либо класс (с функцией рендеринга).
Если реакция увидит класс или функцию в качестве первого аргумента, она проверит, какой элемент он отображает, учитывая соответствующие реквизиты, и будет продолжать делать это до тех пор, пока не будет больше createElement вызовов, которые имеют класс или в качестве их первого аргумента.
Когда React видит элемент с типом функции или класса, он консультируется с этим компонентом, чтобы узнать, какой элемент он должен вернуть, учитывая соответствующие реквизиты.
В конце этого процесса у React будет полное объектное представление дерева DOM. Весь этот процесс называется согласованием в React и запускается каждый раз, когда вызывается setState или ReactDOM.render .
Синтаксис класса — один из наиболее распространенных способов определения компонента React. Хотя он более подробный, чем функциональный синтаксис, он предлагает больше контроля в виде ловушек жизненного цикла.
- Мы можем отображать множество экземпляров одного и того же компонента.
- Экземпляр — это ключевое слово this, которое используется внутри компонента на основе классов.
- Не создается вручную и находится где-то в памяти React.
Создать компонент класса
Использовать в любом другом компоненте
Доступ к реквизитам можно получить с помощью this.props
Использование ловушек жизненного цикла
- Не иметь экземпляров.
- Может рендериться несколько раз, но React не связывает локальный экземпляр с каждым рендерингом.
- React использует вызов функции, чтобы определить, какой элемент DOM отображать для функции.
С тем, что возвращает createElement
Здесь у нас есть компонент Button , который принимает ввод onLogin и возвращает элемент React.
- Компонент Button получает метод onLogin в качестве своего свойства.
- Чтобы передать это в наше объектное представление DOM, мы передадим его в качестве второго аргумента для createElement, точно так же, как мы сделали это с атрибутом id .
React Element — это простой объект, описывающий узел DOM и его атрибуты или свойства, которые вы можете назвать. Это неизменяемый объект описания, и вы не можете применять к нему какие-либо методы.
React Component — это функция или класс, который принимает ввод и возвращает элемент React. Он должен хранить ссылки на свои узлы DOM и на экземпляры дочерних компонентов.
Компонент — это фабрика для создания элементов.
Элемент — это простой объект, описывающий то, что вы хотите отобразить на экране с точки зрения узлов DOM или других компонентов. Элементы могут содержать другие элементы в своих свойствах. Создание элемента React дешево. После того, как элемент создан, он никогда не мутирует. Объектное представление элемента React будет следующим:
Вышеупомянутый createElement возвращает как объект, как показано ниже,
И, наконец, он рендерится в DOM с помощью ReactDOM.render, как показано ниже:
В то время как component может быть объявлен несколькими различными способами. Это может быть класс с методом render(). В качестве альтернативы, в простых случаях, его можно определить как функцию. В любом случае он принимает свойства в качестве входных данных и возвращает дерево элементов в качестве выходных данных. JSX транспилируется как createElement в конце.
Element — это то, что описывает, как построить VDOM. По сути, это «замороженная» версия соответствующего Component Instance .
Если бы все было functional component , тогда не было бы необходимости в дополнительной реакции Element . Иерархия functional component может создавать дерево VDOM напрямую.
Иерархия реакции Component Instance ( tree ) является «фабрикой», и эта фабрика параметризуется реквизитами, которые подаются в корневую реакцию Component Instance , и всем состоянием, «сохраненным» где угодно в дереве Component Instance .
Таким образом, реакция Element представляет собой «абстрактное синтаксическое дерево», которое компилируется в фактический VDOM.
Так почему бы не сгенерировать VDOM напрямую, используя реакцию Component Instances ? Это реальный вопрос здесь.
На первый взгляд, я не понимаю, почему это невозможно сделать. Так что, скорее всего, ответ заключается в том, что это вопрос производительности.
Реакт Element — это один слой абстракции между VDOM и Component Instance , зачем нужна эта абстракция мне не совсем понятно, скорее всего она позволяет проводить оптимизации. Например, дерево Element не отображается полностью, если какой-либо метод жизненного цикла в Component Instance говорит, что нет необходимости отображать это поддерево.
Теперь, в этом случае, логика, которая обрабатывает эту оптимизацию, «нуждается» в этом дополнительном уровне косвенности — потому что информация должна храниться где-то, чтобы какую-то часть VDOM нельзя было сравнивать с новым VDOM, даже больше, может быть, с новым ВДОМ вообще не надо даже рассчитывать. Таким образом, использование дополнительного уровня косвенности упрощает логику рендеринга и приводит к более чистой и удобной в сопровождении реализации.
Эта концепция в Haskell называется «lifting»:
Например, монады в Haskell — прекрасный пример такого поднятия.
Монада — это своего рода описание вычисления, которое может храниться как значение, например 42 . Точно так же react Elements — это элементы описания того, как вычислить «новый» VDOM. Если кто-то хочет вычислить это.
В этом докладе эта концепция «дополнительной» косвенности описывается на нескольких простых примерах:
Другими словами: преждевременная оптимизация — корень всех зол.
Фундаментальная теорема программной инженерии (FTSE) — это термин создан Эндрю Кенигом для описания замечания Батлера Лэмпсона1 приписывается покойному Дэвиду Дж. Уиллеру:2
Мы можем решить любую проблему, добавив дополнительный уровень косвенности.
Итак, в моем понимании, react Elements — это деталь реализации, позволяющая изящно справляться со сложностью и позволять некоторую оптимизацию (производительность). Я не понимаю, почему нельзя было избавиться от этой дополнительной косвенности — в принципе — реакция по-прежнему будет работать «так же хорошо» — но она может быть очень медленной, реализация и поддержка самого «движка» реакции, вероятно, будет кошмаром. .
Пожалуйста, поправьте меня, если я что-то здесь упустил.
Цитирование ВАЖНОЙ части ответа пользователя6445533:
type , строка, представляющая HTML-тег или ссылку, указывающую на Реагировать Компонент
Элемент НЕ ВДОМ.
React Element — это то, что вы считаете базовым элементом html (точнее, dom). Это просто способ создания элемента без использования спорного формата jsx.
React Component — это то, что вы можете рассматривать как объект. Он имеет свои методы, поддерживает React lifecycles и, как правило, непригоден для использования (по крайней мере, повторного использования пока не нашел, добро пожаловать в примеры). Он обязательно должен иметь функцию рендеринга.
React Class — это то, что вы называете классом. Функционально React Class и React Component одинаковы. Реальным изменением является только синтаксис, так как React Component основан на ES6 syntax . Еще одним важным изменением является то, что привязка функций по умолчанию к this больше не поддерживается, если только не используются функции стрелок. Mixins также больше не поддерживаются с ES6 .
Вопросы про React на собеседовании¶
Что происходит, когда вы вызываете setState ?¶
Если был вызван setState , то React захочет объединить объект, который вы отправили в setState с текущим состоянием компонента. Это позволит начать процесс согласования. Конечной целью согласования является обновление пользовательского интерфейса на основе его нового состояния наиболее эффективным из возможных способов.
Для этого React сформирует новое дерево элементов (которое можно рассматривать как объектное представление вашего пользовательского интерфейса). Как только React получает это дерево, чтобы выяснить как интерфейс должен измениться в ответ на новое состояние, React сравнит новое дерево с предыдущим деревом элементов. В этом процессе, React узнает точные изменения, которые произошли. Зная эти изменения, React получит возможность провести изменения в интерфейсе только там, где это необходимо и этим минимизировать количество изменений.
Какая разница между Элементом и Компонентом в React?¶
Проще говоря, элемент в React описывает то, что вы хотите видеть на экране. Если не проще, то элемент в React является объектным представлением некого пользовательского интерфейса.
Компонент в React является функцией или классом, который при необходимости принимает данные и возвращает элемент (обычно в виде JSX, который преобразуется в вызов createElement )
Когда вам использовать Class Component вместо Functional Component?¶
Если ваш компонент имеет состояние или содержит используемые методы значимые для компонента, то используйте Class component. В других случаях используйте Functional component.
Что за refs в React и в чем их важность?¶
Refs являются запасным выходом, который позволяет вам получить прямой доступ к элементу DOM или состоянию компонента. Чтобы их использовать вы добавляете атрибут ref в ваш компонент, значение которого является функцией обратного вызова, которая получит базовый элемент DOM или установленный экземпляр компонента в качестве первого аргумента.
Отметим, что наше поле ввода имеет атрибут ref , значение которого является функцией. Эта функция получает реальный элемент DOM на вход, который мы затем вставим в экземпляр для того, чтобы получить доступ к нему внутри функции handleSubmit .
Часто неверно полагают, что необходимо использовать класс компонента для того, чтобы использовать refs, но refs могут быть использованы с функциональными компонентами за счет использования замыкания:
Что за keys в React и чем их важность?¶
Keys (ключи) помогают React отследить какие элементы были изменены, добавлены или удалены из списка.
Важно, чтобы каждый ключ был уникальным между “собратьями”. Мы уже говорили о процессе согласования и в частности о процессе сравнения нового дерева элементов с предыдущим. Keys делают этот процесс более эффективным при работе со списками, потому что React может использовать ключ на дочерний элемент, чтобы быстро узнать если элемент является новым или если он был просто перемещен при сравнении деревьев элементов. Не только keys делают этот процесс более эффективным, но без них, React не сможет узнать какое локальное состояние соответствует какому пункту при его перемещении. Поэтому не пренебрегайте использованием keys при применении map.
Если вы создали в React элемент Twitter как в примере ниже, то как бы он выглядел?¶
Если вы не очень хорошо знакомы с шаблоном render callback, это может показаться немного странным. В этом шаблоне компонент получает функцию в качестве своего потомка. Обратите внимание, что находится внутри тега <Twitter> выше. Вместо другого компонента, как вы возможно видели до этого, потомок компонента Twitter является функцией. Это означает то, что в данной реализации компонента Twitter нам необходимо обратиться к props.children как к функции.
Вот как я вижу это решение:
Обратите внимание, что, как упоминал выше, я обращаюсь к props.children как к функции, вызывая ее и передавая пользователя.
Что хорошего в этом шаблоне, это то, что мы выделили наш родительский компонент из нашего дочернего компонента. Родительский компонент управляет состоянием и потребитель родительского компонента может решить каким образом они хотели бы использовать переданные аргументы в их интерфейсе, полученные из родительского.
Чтобы продемонстрировать это, давайте примем, что в другом файле мы хотим отрисовать Profile вместо Badge, и так как мы используем шаблон render callback, мы можем менять окружение интерфейса без изменения нашей реализации родительского компонента Twitter .
В чем разница между controlled и uncontrolled компонентами?¶
Одна из основных идей React, это наличие контроля над компонентами и управление их собственным состоянием. Что случится если мы отправим чистый HTML элементов формы ( input , select , textarea и т. д.) в общей куче? Должны ли мы иметь React, как “единственный источник правды” или мы должны позволить, чтобы данные формы существовали в DOM в HTML-форме? Эти два вопроса лежат в основе контролируемых (controlled) и неконтролируемых (uncontrolled) компонентов.
Контролируемый компонент — это такой компонент, где React осуществляет контроль и является единственным источником правды для данных формы. Как вы можете видеть ниже, username существует не в DOM, а нашем состоянии компонента. Всякий раз, когда хотим обновить username , мы вызываем setState , как мы уже привыкли.
Некотролируемый компонент — это такой компонент, где ваши данные формы обрабатываются в DOM, а не внутри вашего компонента.
Хотя неконтролируемые компоненты обычно проще в реализации, так как вы просто берете значение из DOM используя refs, рекомендуется использовать контролируемые компоненты. Основная причина этого в том, что контролируемые компоненты поддерживают мгновенную проверку полей, позволяют вам условно отключать/включать кнопки, устанавливать формат входных данных и вообще следует более сути React.
В какой момент жизненного цикла вы применяется AJAX запросы и почему?¶
AJAX запросы должны идти в момент события componentDidMount .
Для этого есть несколько причин:
- Следующая реализация алгоритма сверки в React будет иметь возможность запускать и останавливать рендеринг для повышения производительности. Одним из компромиссов является то, что componentWillMount , другой цикл событий, где, возможно, стоит реализовать AJAX-запрос, будет “не детерминированным”. Это означает то, то React может начать вызывать componentWillMount в разное время, когда он чувствует в этом необходимость. Это, очевидно, плохая формула для создания AJAX-запроса.
- Вы не можете гарантировать, что AJAX-запрос не будет разрешен (resolve) перед моментом монтирования компонента. Если да, то это будет означать, что вы пытаетесь выполнить setState над демонтированным компонентом, который не только не работает, но и сам React будет ругаться на вас. Делайте AJAX-запросы в componentDidMount , чтобы гарантировать, что есть компонент для обновления.
Что делает и почему важен shouldComponentUpdate?¶
Выше мы уже говорили о сверке и что делает React когда вызван setState . Что делает shouldComponentUpdate , это метод жизненного цикла, который позволяет нам от процесса сравнения для некоторых компонентов (и их дочерних компонентов). Зачем нам это вообще нужно делать? Как отмечалось выше, “цель сравнения в том, чтобы самым эффективным путем обновить интерфейс на основе нового состояния”. Если вы знаете, что часть интерфейса не изменится, то нет причин, заставлять React пройти через трудности, чтобы понять это. При возвращения false из shouldComponentUpdate , React будет понимать, что текущий компонент и все его дочерние компоненты останутся такими же, какими являются в данный момент.
Как вы скажете React строить в режиме Production и как это сделать?¶
Обычно вы можете использовать метод DefinePlugin в Webpack для установки NODE_ENV в production . Это вырежет такие вещи, как propType валидацию и другие предупреждения. Кроме того, это хорошая идея, чтобы минимизировать ваш код, потому что React использует Uglify для удаления “мертвого кода” в виде самого кода и комментариев, что позволит сильно уменьшить размер сборки.
Почему необходимо использовать React.Children.map вместо props.children.map() ?¶
Почему необходимо использовать React.Children.map(props.children, () => ) вместо props.children.map(() => ) ?
Нет гарантии, что props.children будет массивом.
Взгляните на код:
Если внутри Parent в попытаетесь вызвать props.children.map это вызовет ошибку, потому что props.children является объектом, а не массивом.
React отработает с props.children только в том случае, если родитель имеет более одного дочернего элемента, как здесь:
Вы должны использовать React.Children.map , потому что эта реализация учитывает, что props.children может быть как объектом, так и массивом.
Опишите, как в React обрабатываются события?¶
Чтобы решить проблемы кроссбраузерной совместимости, вашим обработчикам в React будут переданы экземпляры SyntheticEvent , которые являются в React обертками над нативными событиями браузеров. Эти искусственные события имеют такой же интерфейс как и у нативных методов, которые вы используете, за исключение того, что они одинаково хорошо работают во всех браузерах.
Интересно то, что React не назначает события на дочерние элементы сам. React будет слушать все события на верхнем уровне, используя простой слушатель событий. Это хорошо для производительности и также означает, что React не нужно беспокоиться об отслеживании при обновлении DOM.
В чем разница между createElement и cloneElement?¶
createElement мы получаем из JSX и его React использует для создания элементов (объектное представление некоторого интерфейса). cloneElement используется для клонирования элемента и отправить ему новые параметры.
Какой второй аргумент можно передать опционально в setState и какова его цель?¶
Так как функция setState асинхронная, то вторым параметром она может принимать функцию обратного вызова, которая будет вызывана после выполнения setState и отрисовки компонента. Как правило, вместо функции обратного вызова лучше использовать метод componentDidUpdate .
Что не так с этим кодом?¶
С кодом все отлично 🙂 Такой вариант редко используется и не достаточно хорошо известен, но вы можете отправить функцию в setState , которая получает предыдущее состояние и параметры props и возвращает новое состояние, также как мы делали выше. И это не только не плохой код, а, более того, является рекомендуемым если вы получаете новое состояние на основании предыдущего.
компонент (элемент)
3.5 компонент (элемент) (component part): Неразделимая часть электрооборудования.
Примечание — Совокупность таких компонентов может составлять электротехническое устройство.
3.5 компонент (элемент) (component part): Неделимая часть оборудования.
Примечание — Совокупность таких частей составляет электротехническое устройство.
Словарь-справочник терминов нормативно-технической документации . academic.ru . 2015 .
Полезное
Смотреть что такое «компонент (элемент)» в других словарях:
компонент — элемент, составляющая, компонента, составная часть, деталь, звено, схема, устройство; фитерал, ингредиент Словарь русских синонимов. компонент см. часть Словарь синонимов русского языка. Практический справочник. М.: Русский язык. З. Е.… … Словарь синонимов
компонент — 3.1 компонент (component): Часть, блок или сборочная единица, выполняющая определенную функцию в гидросистеме. Примечание Данное определение отличается от приведенного в ИСО 5598, поскольку включает соединители, трубы и шланги, которые исключены… … Словарь-справочник терминов нормативно-технической документации
КОМПОНЕНТ — [лат. componens (components) составляющий] составная часть чего л. Словарь иностранных слов. Комлев Н.Г., 2006. компонент (лат. componens (compo nentis) составляющий) составная часть чего л. Новый словарь иностранных слов. by EdwART, , 2009 … Словарь иностранных слов русского языка
элемент — компонент, компонента, деталь, звено, схема, устройство, составляющая, (составная) часть, ингредиент, штука, штучка, начало, член, секция, клетка, привкус, оттенок, налет, доза, доля, термопара; тип, субъект, молодчик, субчик, гаврик, хмырик,… … Словарь синонимов
элемент — а, м. élément m., нем. Element <лат. elementum стихия, первоначальное вещество. 1. У древнегреческих философов материалистов одна из составных частей природы (огонь, вода, воздух, земля), лежащих в основе всех вещей, явлений; стихия. БАС 1.… … Исторический словарь галлицизмов русского языка
компонент — ▲ элемент ↑ множество компонент[а] элемент множества; логический элемент. ингредиент. составляющая. первооснова. абсолют. первоэлемент. субстанция. субстрат. ▼ фактор, подмножество, АТМОСФЕРНАЯ ВЛАГА ↓ … Идеографический словарь русского языка
ЭЛЕМЕНТ — (лат. elementum первоначальное вещество, стихия). 1) простое или не разлагаемое тело, как напр, серебро, медь, азот и пр. 2) малые частицы, из которых состоит тело. 3) начальное вещество, стихия. Словарь иностранных слов, вошедших в состав… … Словарь иностранных слов русского языка
Компонент — термин формалистической поэтики; простейший, неразложимый элемент поэтической композиции, простейшая «составная часть» художественного произведения, определяемая по ее композиционной функции как инвентарный или статический мотив, как динамический … Литературная энциклопедия
компонент данных — элемент набора данных — [Л.Г.Суменко. Англо русский словарь по информационным технологиям. М.: ГП ЦНИИС, 2003.] Тематики информационные технологии в целом Синонимы элемент набора данных EN data member … Справочник технического переводчика
ReactJS: компоненты, элементы и экземпляры
Многие люди не всегда понимают разницу между компонентами, их экземплярами и элементами в React. Почему существуют три различных термина для обозначения чего-то, что нарисовано на экране?
Если вы новичок в React, то вероятно вы до этого работали только с классами компонента и экземплярами. Например, вы можете объявить компонент Button, создав класс. Когда программа запущена, вы можете иметь несколько экземпляров этого компонента на экране, каждый со своими свойствами и локальным состоянием. Это традиционное объектно-ориентированное программирование пользовательского интерфейса (UI). Зачем вводить элементы?
В традиционной модели UI, это заставляет вас заботится о создании и уничтожении экземпляров компонентов ребенка. Если компонент Form хочет отрисовать компонент Button, он должен создать его экземпляр и собственноручно держать его в курсе любой новой информации.
Это абстрактный код, но он в той или иной степени показывает, что вы получите при попытке написать составного UI, который ведет себя последовательно, согласно объектно-ориентированному принципу фреймворка наподобие Backbone.
Каждый компонент должен держать ссылку на его узел DOM и экземпляры дочерних компонентов, и создание, обновление, и уничтожение их, когда это будет необходимо. Строки кода растут как квадрат числа возможных состояний компонента и родители имеют непосредственный доступ к экземплярам компонентов своих потомков, делающее сложным процесс разделения их в будущем.
Теперь давайте поговорим о React.
В React, вот где элемент приходит на помощь. Элемент является простым объектом, описывающим экземпляр компонента или узел DOM и его необходимы свойства. Он содержит только информацию о типе компонента (например, Button), его свойства (например, color) и на любый дочерние элементы внутри него.
Элемент не является фактическим экземпляром. Скорее, это способ сказать React, что вы хотите видеть на экране. Вы не можете вызвать любой метод на элемент. Это просто неизменный описанный объект с двумя полями: type: (string | Component) and props: Object.*
В случае когда тип элемента строка (string), элемент представляет собой узел DOM с типом тега, указанным в содержимом типа, и параметрами соответствующими его атрибутам. Это то, что React отрисует. Например:
Подобный элемент является лишь способом представить этот HTML как простой объект:
Рассмотрим как элемент может быть вложенным. Условно, когда мы хотим создать элемент-дерево, мы указываем один или более дочерних элементов как свойства ребенка содержащих их.
Важно то, что и дочерний, и родительский элементы являются просто описанием, а не экземпляром. Вы можете создать или выбросить их и это не будет иметь большого значения.
Элементы в React легко перемещать, без необходимости обработки (parsed), и, конечно, они гораздо легче, чем реальные элементы DOM — они просто объекты!
Однако, тип элемента может быть еще и функцией или классом соответствующим компоненту React:
Это одна из основных идея React.
Элемент описывает компонент также является элементом, также как элемент описывающий узел DOM. Они могут быть вложенными или смешанными с другими.
Эта возможность позволяет вам определить компонент DangerButton как Button со своим значением параметра color не переживая о том, что будет ли Button отрисован как button, div или совершенно другое.
Вы можете смешать и подогнать их позже:
Или если вы предпочитаете JSX:
Это сохраняет детали компонентов разделенными друг от друга и они могут выразить отношение “имеет” и “является” только через состав.
Когда React видит элемент с типом класс или функция, он будет знать, что необходимо опрашивать его как компонент и отрисовывать с заданными параметрами.
React опросит Button что он отрисовывает и получит это:
React будет повторять данный процесс до тех пор, пока он не узнает базовые элементы (теги) HTML для каждого компонента страницы.
React как ребенок спрашивающий “что такое Y” для каждого “X есть Y” до тех пор, пока он не определить каждую мелочь в мире.
Помните пример Form выше? Он может быть написан в React следующим способом*:
Вот так просто! Для компонента React параметры являются входными и дерево элементов выходными.
Возвращенное дерево элемент может содержать как элементы описывающие узлы DOM, так и элементы описывающие другие компоненты. Это позволяет вам создавать независимые части интерфейса не полагаясь на их внутренние DOM структуры.
Мы позволяем React создавать, обновлять и уничтожать экземпляры. Мы описываем элементы возвращаемые из компонентов, а сам React берет на себя заботу об управлении экземплярами.
К коде выше Form, Message и Button являются компонентами React. Они могут быть записаны как функции, как выше, или как классы нисходящие из React.Component:
Когда компонент определяется как класс, это немного более мощная реализация, чем функциональный компонент. Он может хранить некоторое локальное состояние и выполнять заданную логику, когда соответствующий узел DOM создан или разрушен. Функциональный компонент менее мощный но он более простой и он действует как класс компонента просто с одним методом render().
Однако, будь то функции или классы, принципиально они все являются компонентами React. Они получают параметры как входные данные и возвращают элементы как выходные.
Когда вы вызываете
React спросит компонент Form какое дерево элемент он возвращает, учитывая полученные параметры. Это позволит постепенно “совершенствовать” его понимание вашего дерево-компонента с точки зрения простых примитивов:
В конце этого процесса React знает итоговое дерево DOM и визуализирует посредством ReactDOM или React Native применяет минимальный набор необходимых изменений для обновления актуальных узлов DOM.
Этот постепенный процесс уточнения является также причиной простоты оптимизации приложений на React. Если некоторые части вашего дерева-компонента становятся слишком большими для React для эффективной обработки, вы можете сказать ему пропустить “уточнение” и сравнить некоторые части дерева если соответствующие параметры (props) не изменились. Очень быстро вычислить, являются ли параметры измененными если они были изменены, так React и процесс изменения великолепны вместе и могут обеспечивать великолепную оптимизацию с минимальными усилиями.
Вы могли заметить, что я много сказал о компонентах и элементах и не так иного об экземплярах. Это правда, экземпляры имеют в React гораздо меньшее значение в React, чем в большинстве объектно-ориентированных UI фреймворках.
Только компоненты были объявлены как классы имеют экземпляр и вам никогда не создать их непосредственно: React делает это за вас. /Есть несколько механизмов для экземпляра родительского компонента для доступа в экземпляр дочернего компонента, они используются только для принудительных действий (таких, как установка фокуса на поле) и их, как правило, следует избегать.
React заботится о создании каждого экземпляра для каждого класса компонента, так что вы можете писать компоненты в объектно-ориентированном стиле с методами и локальными состояниями, но кроме этого, экземпляры не очень важны в модели программирования в React и управляются сами React.
Вывод
Элемент — это простой объект описывающий, что вы хотите чтобы появилось на экране в терминах узлов DOM или других компонентов. Элементы могут содержать другие элементы в своих параметрах.
Компонент — может быть двух видов. Он может быть классом с методом render(), который наследуется из React.Component. Или он может быть функцией. В обоих случаях, он принимает параметры на вход и возвращает элемент дерева на выходе.
Когда компонент получает параметры на входе, это означает, что родительский компонент возвращает элемент с его типом и его параметрами.
Вот почему люди говорят, что параметры текут в одну сторону в React: от родителя в ребенку.
Экземпляр — это то, на что вы ссылаетесь как this в классе компонента, который вы пишете.
Функциональный компонент не имеет экземпляров. Класс компонента имеет экземпляры, но вам нет необходимости создавать экземпляры компонента непосредственно — React берет на себя данную заботу.