Что такое компонент в js
Перейти к содержимому

Что такое компонент в js

  • автор:

Веб-компоненты проще, чем вы думаете

Когда я приходил на конференции и видел презентации на тему веб-компонентов, я всегда думал, что это не только изящно, но и довольно сложно. Тысяча строк JavaScript, чтобы сохранить всего 4 строки HTML. Докладчик или неизбежно скрывал за простыми вещами огромное количество JS кода, или погружался в сложные детали, тогда мои глаза начинали закрываться от скуки, и я начинал думать о том, покрывают ли мои суточные выплаты расходы на закуски.

Однако в недавнем проекте, созданном для легкого изучения HTML (Конечно, путем добавления зомби и глупых шуток), я решил, что необходимо описать каждый элемент HTML в спецификации. Не считая той конференции, я впервые начинал знакомство с и элементами, и, когда я захотел написать что-то интересное о них в проекте, мне пришлось углубиться в тему.

И в процессе углубления я понял: веб-компоненты проще, чем я думал.

Либо веб-компоненты прошли долгий путь развития с тех пор, как я мечтал о закусках на конференции, либо я позволил моему изначальному страху помешать по-настоящему узнать их, а возможно и то, и другое.

Я здесь, чтобы сказать вам: да, вы можете создать веб-компонент. Давайте оставим страх и даже закуски за дверью, чтобы сделать все вместе.

Начнем с

— это HTML элемент, позволяющий создать нам шаблон (HTML структуру для веб-компонентов).

Код

 

Элемент — очень важный, потому что позволяет держать все вместе. Это как база для вашего дома, база, с которой начинает строиться все, что мы называем готовым зданием. Давайте использовать этот небольшой фрагмент кода для нашего компонента, который оповещает нас о наступлении зомби-апокалипсиса.

Тогда есть компонент

— это всего лишь HTML элемент, как и . Но в нашем случае настраивает то, что отображает на странице.

Код

 

Здесь мы добавили слот со словом «Zombies» (Слово ли это?) в разметку . Если мы ничего не делаем со слотом, по умолчанию он отображает контент между тегами. В нашем случае это будет «Zombies».

Использование похоже на placeholder . Мы можем использовать placeholder , тогда будет отображаться подсказка, или указать что-то другое вместо placeholder . В веб-компонентах это достигается с помощью атрибута name .

Код

 

name атрибут сообщает веб-компоненту о том, какое содержание должно быть отображено в . Прямо сейчас у нас есть «whats-coming» слот. Мы предполагаем, что зомби придут первыми при наступлении зомби-апокалипсиса, но дает нам гибкость, чтобы вставить что-то еще, если окажется, что первыми придут роботы или оборотни.

Использование веб-компонента

Технически, мы закончили писать собственный компонент и уже можем вставить в любое место, где захотим (Примечание переводчика: для полноценной работы компонента необходимо написать немного JS кода, о чем говорится далее).

Код

 Halitosis Laden Undead Minions  

Видите, что мы делаем? Мы помещаем компонент на страницу так же, как и любой другой HTML элемент. Однако мы добавили в слот «whats-coming». и его содержимое будет отображено на месте «Zombies», когда компонент отобразится.

Стоит обратить внимание, что в названиях веб-компонентов должен быть дефис, чтобы предотвратить конфликт с HTML элементами, которые могут быть добавлены браузерами позже. Это то, о чем вы должны знать, когда дело касается веб-компонентов.

Все еще со мной? Не так уж и страшно, не правда ли? Что ж, минус зомби. Нам еще надо будет немного поработать, чтобы сделать замену возможной, именно здесь мы начинаем знакомство с JavaScript.

Регистрация компонента

Как я уже сказал ранее, вам нужно немного JavaScript кода, чтобы все это работало, но это не очень сложный, многострочный и глубокий код, как я всегда думал. Надеюсь, я смогу убедить вас в том, что все просто.

Вам нужна функция-конструктор, которая регистрирует веб-компонент. Иначе наше компоненты будет как нежить: она есть, но не полностью живая.

Вот конструктор, который мы будем использовать.

Код

// Определяем собственный веб-компонент с подходящим именем customElements.define("apocalyptic-warning", class extends HTMLElement < // Наследование обеспечивает, что мы имеет свойства и методы по умолчанию встроенного HTML элемента // Вызывается всякий раз, когда создается новый элемент constructor() < // Вызываем родительский конструктор, т.е конструктор для HTMLElement. Таким образом устанавливаются свойства базового HTML элемента. super(); // Берет и хранит его в переменной `warinng` let warning = document.getElementById("warningtemplate"); // Хранит контент шаблона в переменной `mywarning` let mywarning = warning.content; const shadowRoot = this.attachShadow().appendChild(mywarning.cloneNode(true)); > >);

Я оставил в коде подробные построчные комментарии, но не объяснил код на последней строке.

Код

const shadowRoot = this.attachShadow().appendChild(mywarning.cloneNode(true));

Мы здесь делаем много работы. Во-первых, мы берем наш веб-компонент (this) и создаем скрытого шпиона, я имею в виду Shadow DOM. < mode: open >означает, что JavaScript может извне :root обращаться к элементам Shadow DOM и управлять ими, что-то вроде настройки доступа к компоненту через черный вход. Был создан Shadow DOM и мы добавляем к ней узел (Примечание переводчика: HTML Node). Этот узел будет полной копией шаблона, включая все элементы и текст шаблона. С шаблоном, прикрепленным к Shadow DOM из пользовательского компонента, элемент и slot атрибут берут на себя задачу сопоставления содержимого с тем, где оно должно находиться.

Проверьте это. Теперь мы можем объединить экземпляр одного и того же веб-компонента, отображая разный контент, просто изменив один элемент.

Код

customElements.define('apocalyptic-warning', class extends HTMLElement < constructor() < super(); let warning = document.getElementById('warningtemplate'); let mywarning = warning.content; const shadowRoot = this.attachShadow().appendChild(mywarning.cloneNode(true)); > >);

The Apocalypse will never happen!

Undead Halitosis Laden Zombie Minions

Стилизация компонента

Возможно, вы заметили стилизацию в нашем примере. Как и следовало ожидать, у нас есть абсолютно все возможности для стилизации наших компонентов в CSS. На самом деле, мы можем включить элемент прямо в .

Код

 

Таким образом, стили применяются только для компонента, что позволяет изолировать их благодаря теневой модели Shadow DOM.

Я предположил, что пользовательский компонент берет копию шаблона, вставляет контент, который вы добавили, и внедряет его на страницу, используя Shadow DOM. Хотя может показаться, что работа Shadow DOM похожа на обычное DOM дерево, но это не так. Контент в веб-компоненте остается на месте, а теневой DOM как бы накладывается сверху.

И с этого момента контент технически находится вне шаблона, любые селекторы и классы, используемые в шаблонном , не будут действовать на контент внутри . Это не позволяет достичь полной инкапсуляции, чего я ожидал. Но поскольку веб-компонент является элементом, мы можем использовать его как селектор элемента в любом CSS файле, включая основной файл, используемый на странице. И хотя вставленный контент технически не находится в шаблоне, он находится в веб-компоненте, где доступна стилизация через селекторы потомков CSS.

Код

apocalyptic-warning span

Будьте осторожны, стили в основном файле CSS не могут получить доступ к внутренним элементам .

Код JavaScript точно такой же, за исключением того, что сейчас мы работаем с компонентом, у которого другое имя, .

Код

customElements.define("zombie-profile", class extends HTMLElement < constructor() < super(); let profile = document.getElementById("zprofiletemplate"); let myprofile = profile.content; const shadowRoot = this.attachShadow().appendChild(myprofile.cloneNode(true)); > > );

Вот шаблон HTML и инкапсулированный CSS.

Код

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

Код

zombie-profile < width: calc(50% - 1em); border: 1px solid red; padding: 1em; margin-bottom: 2em; display: grid; grid-template-columns: 2fr 4fr; column-gap: 20px; >zombie-profile img < width: 100%; max-width: 300px; height: auto; margin: 0 1em 0 0; >zombie-profile li, zombie-profile ul < display: inline; padding: 0; >zombie-profile li::after < content: ', '; >zombie-profile li:last-child::after < content: ''; >zombie-profile li:last-child::before

А вот и результат:

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

Вот и все. Чего вы сейчас боитесь больше: веб-компонентов или зомби-апокалипсиса? В недалеком прошлом я бы мог сказать, что веб-компонентов, но теперь зомби — единственное, что меня беспокоит (Ну, и покроют ли мои суточные выплаты расходы на закуски).

Веб-компоненты

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

Понятия и использование

Как разработчики, все мы знаем, что как можно больше повторного использования кода — хорошая идея. Традиционно это было не так просто для пользовательских структур разметки — подумайте о сложном HTML (и связанном с ним стиле и сценарии), которые вам иногда приходилось писать для визуализации пользовательских элементов управления UI, и о том, как их многократное использование может превратить вашу страницу в беспорядок если вы не будете осторожны.

Веб-компоненты направлены на решение таких проблем — они состоят из трёх основных технологий, которые можно использовать вместе для создания универсальных настраиваемых элементов с инкапсулированной функциональностью, которые можно повторно использовать где угодно, не опасаясь коллизий кода.

  • Пользовательские элементы: набор API-интерфейсов JavaScript, позволяющих определять пользовательские элементы и их поведение, которые затем можно использовать по желанию в пользовательском интерфейсе.
  • Shadow DOM: набор API-интерфейсов JavaScript для прикрепления инкапсулированного «теневого» дерева DOM к элементу, который отображается отдельно от DOM основного документа, и управления соответствующими функциями. Таким образом, вы можете сохранить функции элемента в секрете, поэтому для них можно создавать сценарии и стили, не опасаясь коллизий с другими частями документа.
  • HTML templates: элементы и позволяют создавать шаблоны разметки, которых не видно на отображаемой странице. Затем их можно многократно использовать в качестве основы структуры настраиваемого элемента.

Базовый подход к реализации веб-компонента обычно выглядит примерно так:

  1. Создайте класс, в котором вы указываете функциональность своего веб-компонента, используя синтаксис классов ECMAScript 2015 (дополнительную информацию см. в разделе Классы).
  2. Зарегистрируйте свой новый настраиваемый элемент с помощью метода CustomElementRegistry.define() , передав ему имя элемента, который будет определён, класс или функцию, в которых указана его функциональность, и, необязательно, от какого элемента он наследуется.
  3. При необходимости прикрепите теневую DOM к настраиваемому элементу с помощью метода Element.attachShadow() . Добавьте дочерние элементы, обработчики событий и т.д. в теневой DOM, используя обычные методы DOM.
  4. При необходимости определите HTML template, используя и . Снова используйте обычные методы DOM, чтобы клонировать шаблон и прикрепить его к вашей теневой DOM.
  5. Используйте свой настраиваемый элемент везде, где хотите, на своей странице, как и любой обычный элемент HTML.

Учебники

Руководство, показывающее, как использовать функции настраиваемых элементов для создания простых веб-компонентов, а также рассказывает про колбэки жизненного цикла и некоторые другие более сложные функции.

Руководство, которое рассматривает основы теневой DOM, показывает, как прикрепить теневую DOM к элементу, добавлять к теневому дереву DOM, стилизовать его и многое другое.

Руководство, показывающее, как определить повторно используемую структуру HTML с помощью элементов и , а затем использовать эту структуру внутри ваших веб-компонентов.

Справка

Пользовательские элементы

Содержит функции, связанные с настраиваемыми элементами, в первую очередь с методом CustomElementRegistry.define() , используемым для регистрации новых настраиваемых элементов, чтобы их можно было затем использовать в вашем документе.

Возвращает ссылку на объект CustomElementRegistry .

Специальные колбэк-функции, определённые внутри определения класса настраиваемого элемента, которые влияют на его поведение:

  • connectedCallback : вызывается, когда настраиваемый элемент впервые подключается к DOM документа.
  • disconnectedCallback : вызывается, когда пользовательский элемент отключается от DOM документа.
  • adoptedCallback : вызывается, когда настраиваемый элемент перемещается в новый документ.
  • attributeChangedCallback : вызывается при добавлении, удалении или изменении одного из атрибутов настраиваемого элемента.
  • Глобальный атрибут HTML is : позволяет указать, что стандартный элемент HTML должен вести себя как зарегистрированный встроенный пользовательский элемент.
  • Параметр «is» метода Document.createElement() : позволяет создать экземпляр стандартного HTML-элемента, который ведёт себя как заданный зарегистрированный настраиваемый встроенный элемент.

Псевдоклассы, относящиеся конкретно к настраиваемым элементам:

  • :defined : Соответствует любому заданному элементу, включая встроенные элементы и настраиваемые элементы, определённые с помощью CustomElementRegistry.define() .
  • :host (en-US): Выбирает теневой хост теневого DOM (en-US), содержащего CSS, внутри которого он используется.
  • :host() : Выбирает теневой хост теневой DOM (en-US), содержащий CSS, внутри которого он используется (так что вы можете выбрать пользовательский элемент изнутри его теневой DOM) — но только если селектор, указанный в качестве параметра функции, совпадает с теневым хостом.
  • :host-context() : Выбирает теневой хост теневой DOM (en-US), содержащий CSS, внутри которого он используется (так что вы можете выбрать пользовательский элемент изнутри его теневой DOM) — но только если селектор, указанный в качестве параметра функции, совпадает с предком(-ами) теневого хоста в том месте, где он находится внутри иерархии DOM.

Псевдоэлементы, относящиеся конкретно к настраиваемым элементам:

  • ::part (en-US): Представляет любой элемент в теневом дереве (en-US), имеющий соответствующий атрибут part .

Shadow DOM

Представляет корневой узел поддерева теневой модели DOM.

Миксин, определяющий функции, доступные для всех документов и теневых корневых узлов.

Расширения интерфейса Element , связанные с теневой DOM:

  • Метод Element.attachShadow() прикрепляет теневое дерево DOM к указанному элементу.
  • Свойство Element.shadowRoot возвращает теневой корневой узел, прикреплённый к указанному элементу, или значение null , если корневой узел не прикреплён.

Дополнения к интерфейсу Node , относящиеся к теневой DOM:

  • Метод Node.getRootNode() (en-US) возвращает корень объекта контекста, который необязательно включает теневой корневой узел, если он доступен.
  • Свойство Node.isConnected возвращает логическое значение, указывающее, подключён ли узел (прямо или косвенно) к объекту контекста, например объект Document в случае обычного DOM или ShadowRoot (en-US) в случае теневого DOM.

Расширения интерфейса Event , относящиеся к теневой модели DOM:

  • Event.composed (en-US): возвращает Boolean , который указывает, будет ли событие распространяться через границу теневой DOM в стандартную DOM ( true ) или нет ( false ).
  • Event.composedPath (en-US): возвращает путь к событию (объекты, для которых будут вызваны обработчики). Это не включает узлы в теневых деревьях, если теневой корневой узел был создан с закрытым ShadowRoot.mode (en-US).

HTML templates

Содержит фрагмент HTML, который не отображается при первоначальной загрузке содержащего документа, но может отображаться во время выполнения с помощью JavaScript, который в основном используется в качестве основы для структур настраиваемых элементов. Связанный интерфейс DOM — HTMLTemplateElement (en-US).

Заполнитель внутри веб-компонента, который можно заполнить собственной разметкой, что позволяет создавать отдельные деревья DOM и представлять их вместе. Связанный интерфейс DOM — HTMLSlotElement .

Назначает слот элементу в теневом дереве теневого DOM.

Миксин, реализованный как узлами Element , так и Text , определяющий функции, которые позволяют им стать содержимым элемента . Миксин определяет один атрибут, Slotable.assignedSlot (en-US), который возвращает ссылку на слот, в который вставлен узел.

Расширения интерфейса Element , относящиеся к слотам:

  • Element.slot : Возвращает имя слота теневого DOM, прикреплённого к элементу.

Псевдоэлементы, относящиеся конкретно к слотам:

  • ::slotted : Соответствует любому содержимому, вставленному в слот.

Примеры

Мы создаём ряд примеров в репозитории GitHub с примерами веб-компонентов. Со временем будет добавлено больше.

Спецификации

Specification
HTML Standard
# the-template-element
DOM Standard
# interface-shadowroot

Совместимость с браузерами

html.elements.template

BCD tables only load in the browser

api.ShadowRoot

BCD tables only load in the browser

Смотрите также

  • webcomponents.org — сайт с примерами веб-компонентов, учебными пособиями и другой информацией.
  • FAST — это библиотека веб-компонентов, созданная Microsoft, которая предлагает несколько пакетов для использования в зависимости от потребностей вашего проекта. Fast Element — это лёгкое средство для простого создания производительных, эффективных с точки зрения памяти и совместимых со стандартами веб-компонентов. Fast Foundation — это библиотека классов, шаблонов и других утилит веб-компонентов, построенная на основе fast-element, предназначенная для создания зарегистрированных веб-компонентов.
  • Hybrids — библиотека веб-компонентов с открытым исходным кодом, которая предпочитает простые объекты и чистые функции class и this синтаксису. Он предоставляет простой и функциональный API для создания пользовательских элементов.
  • Polymer — каркас веб-компонентов Google — набор полифилов, улучшений и примеров. На данный момент самый простой способ кроссбраузерно использовать веб-компоненты.
  • Snuggsi — Простые веб-компоненты размером ~ 1 КБ, включая полифил — Все, что вам нужно, это браузер и базовое понимание классов HTML, CSS и JavaScript для продуктивной работы.
  • Slim.js — библиотека веб-компонентов с открытым исходным кодом — высокопроизводительная библиотека для быстрой и простой разработки компонентов; расширяемая, подключаемая и кросс-платформенная.
  • Stencil — набор инструментов для создания многоразовых масштабируемых систем проектирования в веб-компонентах.

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 3 авг. 2023 г. by MDN contributors.

Your blueprint for a better internet.

JavaScript компоненты — Введение

Сегодня поговорим о том, как создавать компоненты на чистом JavaScript, которые работают уже сегодня и без полифилов.

Компоненты являются автономными независимыми частями приложения, которые отвечают за обработку только одной задачи и никак не влияют на работу друг друга. У нас уже есть нативные компоненты HTML, такие как инпуты, формы, селекторы, поля, таблицы, изображения и.т.д, но как же добавлять свои собственные, которые будут так-же просто работать?

Текущее ситуация с веб-компонентами

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

На данный момент существует множество UI библиотек и фреймворков, колличество которых увеличивается почти каждую неделю. Самые популярные из них это React JS и VUE. Одна из главных проблем связанных с этими библиотеками, это маркетинговый хайп и огромный размер бандла и слишком большая сложность.

Самый мощный фреймворк JavaScript — это сам JavaScript.

Нужны ли нам дополнительные инструменты? Новый язык / синтаксис, новые излишние уровни абстракции? Повышенный расход ресурсов и время для обработки подобных задач? JavaScript был разработан всего за 10 дней, чтобы его могли использовать простые люди, например дизайнеры, что бы просто реализовывать свои идеи. Независимо от того, что вы уже изучили сегодня — JavaScript по-прежнему является самым мощным, простым и гибким способом решать возложенные на него задачи, и вам не нужна целая инфраструктура для создания современного приложения на JS. Да, веб-тенденции эволюционируют десятимильными в последнее время, и JavaScript следует в ногу с ними.

Как же в таком случае создать простой JavaScript компонент?

Одна из самых мощных функций языка JavaScript которой нет ни в одном другом языке это Объектная Литеральная нотация, а так-же простота и гибкость в создании и изменении объектов. Давайте просто использует это. Вот так просто мы можем создать компонент:

const Button = < tagName: 'btn', init(btn) < btn.addEventListener('click', () =>< btn.textContent++; >); >, getAll(container = document.body) < return container.getElementsByTagName(this.tagName); >>;

Как видите, это просто элементарный объект JavaScript. Более того, недавно я нашел шаблон Object-Speaking pattern без конструктора New и прототипы с использованием идеи, лежащей в основе шаблона factory pattern, простейшегоспособа создания объектов в JavaScript. Почти каждый метод будет получать DOM элемент в качестве первого аргумента. У вас есть только один глобальный объект Button, который срабатывает на всех кнопках в DOM’е, это и есть ваш компонент. Вывам не нужно создавать нкаких новых экземпляров и вы всегда можете получить доступ к любой кнопке из любой части вашего кода без использования шаблона Singleton pattern.

Как реализовывались компоненты JavaScript за многие годы до начала войн современных фреймворков?

Более 10 лет компоненты на чистом JS разрабатывались как плагины для jQuery или автономные виджеты. Проще говоря, это были те самые, простые объекты и функции в JavaScript. В большинстве случаев вы импортировали один файл и просто вызвали метод init(). Когда компонент был бы вставлен в DOM после загрузки кода, как простой выпадающий список, вам приходилось бы вручную вызвать метод init() на новом элементе DOM.

Тем не менее, были доступны события DOM, которые мы могли бы использовать для прослушивания изменений в DOM, таких как добавленный, удаленный или измененный новый тег. Таким образом мы могли бы использовать их для вызова init() или deinit() автоматически. Проблема была в производительности, и из-за этого сегодня у нас есть современный API Mutation Observer, который работает во всех современных браузерах включая IE11.

Вы можете инициализировать только один MutationObserver и прослушивать изменения во всем document.body, а затем регистрировать собственные калбеки, когда, например, новый тег добавляеться в DOM. Поскольку API-интерфейс Mutation Observer и даный алгоритм требуют логической реализации, каждый раз, когда я создаю DOM Observer, который можно легко использовать для работы с подобными задачами, просто вызовите DOMObserver.onInsert(‘tagname’, callback).

Компоненты и свойства

Компоненты позволяют разделить пользовательский интерфейс на независимые, повторно используемые части и работать с каждой из частей отдельно. На этой странице представлено введение в идею компонентов. Здесь вы можете найти подробный справочник API по компоненту.

Концептуально компоненты похожи на функции JavaScript. Они принимают произвольные входные данные (называемые «props» или свойствами) и возвращают React-элементы, описывающие, что должно появиться на экране.

Функциональные и классовые компоненты

Самый простой способ определить компонент — написать JavaScript-функцию:

function Welcome(props)  return h1>Привет, props.name>h1>; >

Данная функция — корректный компонент React, потому что он принимает один аргумент-объект «props» (который обозначает свойства) с данными и возвращает элемент React. Такие компоненты мы называем «функциональными», потому что они являются буквально функциями JavaScript.

Вы также можете использовать класс из ES6 для определения компонента:

class Welcome extends React.Component  render()  return h1>Привет, this.props.name>h1>; > >

Два вышеуказанных компонента эквивалентны с точки зрения React.

У классов есть дополнительные возможности, которые мы обсудим в следующих разделах. До этого момента мы будем использовать функциональные компоненты из-за их краткости.

Раньше мы сталкивались только с элементами React, представляющие DOM-теги:

const element = div />;

Однако элементы также могут быть пользовательскими компонентами:

const element = Welcome name="Сара" />;

Когда React видит элемент, представляющий пользовательский компонент, он передаёт JSX-атрибуты этому компоненту в виде единственного объекта. Мы называем этот объект «props».

Например, этот код отображает «Привет, Сара» на странице:

function Welcome(props)   return h1>Привет, props.name>h1>; > const element = Welcome name="Sara" />; ReactDOM.render( element, document.getElementById('root') );

Давайте посмотрим, что происходит в этом примере:

  1. Мы вызываем ReactDOM.render() с элементом .
  2. React вызывает компонент Welcome с объектом как props .
  3. Наш компонент Welcome возвращает элемент

    Hello, Sara

    в качестве результата.

  4. React DOM эффективно обновляет DOM, чтобы соответствовать

    Hello, Sara

    .

Примечание: Всегда именуйте компоненты с заглавной буквы.

React обрабатывает компоненты, начинающиеся со строчных букв, как DOM-теги. Например, представляет HTML-тег div, но представляет компонент и требует, чтобы Welcome был в области видимости.

Вы можете больше узнать о причинах, лежащих в основе этого соглашения здесь.

Компоненты могут ссылаться на другие компоненты в своём выводе. Это позволяет использовать одну и ту же абстракцию компонента для любого уровня детализации. Кнопка, форма, диалоговое окно, экран: в приложениях React все они обычно являются компонентами.

Например, мы можем создать компонент App , который многократно отрисовывает Welcome :

function Welcome(props)  return h1>Привет, props.name>h1>; > function App()  return ( div> Welcome name="Сара" />  Welcome name="Кахаль" />  Welcome name="Эдит" />  div> ); > ReactDOM.render( App />, document.getElementById('root') );

Как правило, в новых приложениях React есть один компонент App , который находится в самом верху иерархии компонентов. Однако, если вы интегрируете React в существующее приложение, вы можете начать снизу вверх с небольшого компонента, такого как Button , и постепенно идти вверх по иерархии представлений.

Не бойтесь разделять компоненты на более мелкие компоненты.

Например, рассмотрим этот компонент Comment :

function Comment(props)  return ( div className="Comment"> div className="UserInfo"> img className="Avatar" src=props.author.avatarUrl> alt=props.author.name> /> div className="UserInfo-name"> props.author.name> div> div> div className="Comment-text"> props.text> div> div className="Comment-date"> formatDate(props.date)> div> div> ); >

Он принимает author (объект), text (строка) и date (дата) в качестве свойств и описывает комментарий на сайте социальных сетей.

Этот компонент может быть сложно изменить из-за вложенности, а также трудно повторно использовать отдельные его части. Давайте извлечём из него несколько компонентов.

Сначала мы извлечём Avatar :

function Avatar(props)  return ( img className="Avatar"  src=props.user.avatarUrl>  alt=props.user.name>  />  ); >

Компонент Avatar не должен знать, что он отрисовывается внутри Comment . Вот почему мы присвоили свойству объекта props более общее имя: user , а не author .

Мы рекомендуем называть свойства объекта props с точки зрения самого компонента, а не контекста, в котором он используется.

Теперь мы можем чуть-чуть упростить Comment :

function Comment(props)  return ( div className="Comment"> div className="UserInfo"> Avatar user=props.author> />  div className="UserInfo-name"> props.author.name> div> div> div className="Comment-text"> props.text> div> div className="Comment-date"> formatDate(props.date)> div> div> ); >

Затем мы извлечём компонент UserInfo , который отобразит Avatar рядом с именем пользователя:

function UserInfo(props)  return ( div className="UserInfo">  Avatar user=props.user> />  div className="UserInfo-name">  props.user.name>  div>  div>  ); >

Это позволяет нам упростить Comment ещё больше:

function Comment(props)  return ( div className="Comment"> UserInfo user=props.author> />  div className="Comment-text"> props.text> div> div className="Comment-date"> formatDate(props.date)> div> div> ); >

Извлечение компонентов сначала может показаться монотонной работой, но наличие палитры повторно используемых компонентов окупается в больших приложениях. Хорошее правило на этот счёт можно сформировать так — если часть пользовательского интерфейса используется несколько раз ( Button , Panel , Avatar ) или достаточно сложна сама по себе ( App , FeedStory , Comment ), то это хороший кандидат на извлечение компонента, чтобы он стал повторно используемым компонентом.

Свойства объекта props доступны только для чтения

Независимо от того, объявляете ли компонент как функцию или класс, он не должен изменять свои свойства. Рассмотрим эту функцию sum :

function sum(a, b)  return a + b; >

Такие функции называются «чистыми», потому что они не пытаются изменить свои аргументы и всегда возвращают один и тот же результат для одних и тех же входных данных.

Напротив, функция ниже — не чистая, потому что она изменяет свои входные данные:

function withdraw(account, amount)  account.total -= amount; >

React довольно гибкий, но имеет одно строгое правило:

Все React-компоненты должны вести себя как чистые функции в плане своих свойств.

Конечно, пользовательские интерфейсы приложений динамичны и меняются со временем. В следующем разделе мы представим новую концепцию «состояние». Состояние позволяет компонентам React изменять свой вывод с течением времени в ответ на действия пользователя, сетевые ответы и что-либо ещё без нарушения правила выше.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *