Свойства компонента в React.js и их отличие от состояний примеры использования


Содержание материала:

В чем разница между свойством экземпляра компонента React и свойством состояния?

Рассмотрим пример ниже

Когда я нажимаю кнопку, я вижу, что this.counter и this.state.counter показывают увеличенное значение

У меня вопрос, почему я должен использовать государство? хотя ответ способен перерисовать все свойства экземпляра

В приведенном выше фрагменте просто вызов this.setState(<>) делает свое дело, тогда зачем мне использовать свойство this.state для хранения состояния моего компонента?

instance properties state и instance properties служат различным целям. Хотя вызов setState с пустыми аргументами вызовет рендеринг и отразит обновленные свойства экземпляра, состояние можно использовать для многих других функций, таких как сравнение prevState и currentState в shouldComponentUpdate, чтобы решить, хотите ли вы рендерить или нет, или в методе жизненного цикла, например componentDidUpdate, где Вы можете предпринять действие, основанное на изменении состояния.

Состояние — это свойство особого экземпляра, используемое реагированием для специальных целей. Также в setState обновления состояния setState по соображениям производительности, а обновления состояния происходят асинхронно, в отличие от обновлений переменных класса, которые происходят синхронно. Переменная класса не будет иметь этих возможностей.

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

Оба имеют разные цели. Правило большого пальца:

  • Используйте state для хранения данных, если они участвуют в рендеринге или потоке данных (т.е. если они используются прямо или косвенно в методе рендеринга)
  • Используйте other instance fields для хранения данных, если значение НЕ участвует в рендеринге или потоке данных (для предотвращения рендеринга при изменении данных), например, для хранения идентификатора таймера, который не используется в методе рендеринга. См. Пример TimerID в официальных документах, чтобы понять этот действительный случай.

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

Компоненты ReactJS: Основы

ReactJS — это огромная библиотека пользовательского интерфейса (не фрэймворк), завоевавшая большую любовь. Как-то разговаривая с коллегой/другом о ReactJS я услышал от него, что работа с ReactJS не такая интересная, поскольку там слишком много вариантов решения для одной задачи. После некоторого изучения и случайных собеседований я понял, что это как раз таки одна из причин, по которой разработчики сталкиваются с проблемами при работе с этой библиотекой.

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

Заодно мы пробежимся по некоторым полезным темам и терминам в React, которые иногда пугают новичков. А вот темы:

  1. Компонент Родитель
  2. Валидация свойств компонентов
  3. Взаимодействие компонентов
  4. Компонент со значением по умолчанию
  5. ES6+ Компоненты (и различие от normal компонентов)
  6. Бесструктурные компоненты

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

# Стандартный компонент React

Под стандартным компонентом я имею в виду то, что вы возможно, видели в большинстве репозиториев кода и статей:

React Elements против React Components

Несколько месяцев назад я думал, что запостил довольно простой вопрос в Twitter.

Я тщательно подхожу к изучению языка, но у меня до сих пор нет хорошего определения для компонента (React компонента). Есть идеи?

Меня удивила не общая путаница в этом вопросе, а количество неточных ответов, которые я получил:

Такая путаница происходит из-за того, что мы часто не говорим об абстрактном слое между JSX и тем, что на самом деле происходит в React. Для того чтобы ответить на этот вопрос, нам нужно погрузиться в эту абстракцию.

Давайте начнём с рассмотрения основ React. Что такое React? Это библиотека для разработки пользовательских интерфейсов. Как бы сложно React и его экосистема не выглядела, это React и его суть — разработка UI. С этой мыслью, мы подходим к нашему первому определению, Элемент (Element). Простыми словами, React элемент описывает то что вы хотите увидеть экране. А если не простыми, то React элемент описывает узел DOM в виде объекта. Обратите внимание на то, что я использовал слово описывает. Важно, что React элемент это не то что вы увидите на экране, а он описывает то что вы увидите. Для этого есть несколько причин. Первая причина заключается в том, что JavaScript объекты достаточно лёгкие и React может создавать и уничтожать их без слишком большого оверхэда. Вторая причина заключается в том, что React может анализировать объект и анализировать настоящий DOM, а затем обновлять DOM только в том месте, где произошли изменения. Это даёт некоторые плюсы в плане производительности.

Для того чтобы создать объект описывает DOM узел (он же React элемент), мы можем воспользоваться методом createElement .

createElement принимает три аргумента. Первый это название тега (div, span и т.д.), второй это атрибуты которые вы хотите задать элементу и третий это содержимое или дочерний элемент, в нашем случае это текст «Login». createElement вызываемый выше вернёт следующий объект:

и когда он будет отображён в DOM (с помощью функции ReactDOM.render), у нас появиться новый DOM узел, который будет выглядеть следующим образом:

Пока что всё хорошо. Что действительно интересно в изучении React, это то что как правило учат в первую очередь — компоненты. Компоненты — это строительные блоки в React. Однако, заметьте что мы начали эту статью с элементов. Причина по которой мы это сделали, заключается в том, что если вы поймёте элементы, то плавно перейдёте к пониманию компонентов. React компонент — это функция или класс, который принимает входные данные (опционально) и возвращает React элемент.

По определению, у нас есть компонент Button, который принимает функцию onLogin и возвращает React элемент. Надо отметить, что компонент Button получает функцию onLogin в качестве своего свойства. Чтобы передать её в наш объект описывающий DOM, мы передаём её в качестве второго аргумента метода createElement , также как мы передавали наш атрибут id.

До этого момента, мы создавали элементы только с помощью нативных HTML элементов (div, span и т.д.), но мы также можем передавать другие React компоненты в качестве первого аргумента функции createElement .

Однако, в отличии от имени HTML тега, если React увидит класс или функцию в качестве первого аргумента, он проверит какой элемент будет отображаться, учитывая соответствующие свойства. React будет рекурсивно продолжать делать это, пока не останется вызовов createElement без функций или классов в качестве первого аргумента. Давайте посмотрим на это в действии.

В примере выше, у нас есть два компонента, Button и User. Объект User будет отображён как элемент «div» с двумя дочерними элементами, «p» который оборачивает имя пользователя и компонент Button. Теперь давайте заменим вызовы функции createElement на то что они возвращают:

Вы заметили, что вы приведённом выше примере у нас есть 4 разных свойства «type» — «button», «div», «p», and Button. Когда React увидит элемент с функцией или классом в типе (такой как «type: Button» выше), он обратиться к этому компоненту, чтобы узнать что он возвращает, учитывая соответствующие свойства. В конце этого процесса у React есть полный объект представления дерева DOM. В нашем примере оно выглядит следующим образом:

Весь этот процесс в React называется «сверка» (reconciliation) и срабатывает каждый раз, когда вызываются функции setState или ReactDOM.render .

Теперь давайте опять взглянем на наш первоначальный вопрос:

На данный момент у нас есть все необходимые знания для ответа на этот вопрос, за исключением одной важной части. Скорей всего, если вы используете React уже на протяжении какого-то времени, то вы не используете функцию React.createElement для создания объектов описывающих DOM. Вместо этого, вероятно вы используете JSX. Ранее я писал, что «Такая путаница происходит из-за того, что мы часто не говорим об абстрактном слое между JSX и тем, что на самом деле происходит в React». Этот абстрактный слой заключается в том, что JSX всегда компилируется в вызов React.createElement с помощью Babel.

Взгляните на код, из нашего предыдущего примера:

Это результат компиляции следующего JSX кода:

И наконец, как называется действие, когда напишем наш компонент как этот, ?

Мы можем называть это «созданием элемента», потому что после того как JSX будет скомпилирован, именно это и произойдёт.

Все примеры, «создания React элемента»:

Для получения более полной информации прочитайте статью «React Components, Instances, and Elements» от Dan Abramov.

Свойства компонента в React.js и их отличие от состояний: примеры использования

Учебный курс по React, часть 9: свойства компонентов

В сегодняшней части перевода учебного курса по React мы поговорим о свойствах компонентов. Это — одна из важнейших концепций, нашедших отражение в данной библиотеке.

Занятие 19. Свойства компонентов в React

Создадим новый проект средствами create-react-app и изменим код нескольких стандартных файлов из папки src .

Вот код файла index.js :

Вот стили, которые описаны в файле index.css :

Вот код, находящийся в файле App.js :

Вот как будет выглядеть это приложение в браузере.

Страница приложения в браузере

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

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

App возвращает четыре подобных блока, каждый из них можно было бы использовать для создания самостоятельного компонента, но такой подход нас не устраивает. Поэтому создадим один компонент, который станет основой всех карточек, выводимых приложением. Для этого создадим в папке src новый файл компонента — ContactCard.js и поместим в него код, который возвращает первый элемент

Ясно, что если создать несколько экземпляров этого компонента, то все они будут содержать одни и те же данные, так как эти данные жёстко заданы в коде компонента. А нам хотелось бы, чтобы, при создании разных экземпляров этого компонента, можно было бы настраивать выводимые им данные. Речь идёт о том, чтобы компоненту можно было бы передавать некие свойства, которыми он потом сможет воспользоваться.

Мы работаем с функциональными компонентами, которые представляют собой обычные JS-функции, в которых, благодаря использованию библиотеки React, можно использовать особые конструкции. Как известно, функции могут принимать аргументы, хотя их можно использовать и без аргументов. Аналогией нашего компонента ContactCard , в том виде, в котором он сейчас существует, может стать такая вот простая функция, которая, ничего не принимая, просто возвращает сумму двух чисел:

Её можно использовать для того, чтобы узнать сумму чисел 1 и 1, но, например, для того, чтобы сложить 1 и 2, используя функции, которые не принимают никаких входных данных, нам пришлось бы писать новую функцию. Совершенно очевидно то, что такой подход приведёт к огромным неудобствам при необходимости сложения разных чисел, поэтому в подобной ситуации будет разумным создать универсальную функцию для сложения чисел, которая принимает два числа и возвращает их сумму:

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

Импортируем в файл App.js компонент ContactCard и вернём четыре его экземпляра, не удаляя пока код, который формирует карточки на странице приложения:

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

Каждая из карточек содержит четыре фрагмента информации, которые, от карточки к карточке, могут меняться. Это — изображение кошки и её имя, а также телефон и адрес электронной почты. Пусть имя кошки будет содержаться в свойстве name , адрес изображения — в свойстве imgURL , телефон — в свойстве phone , а адрес электронной почты — в свойстве email .

Зададим эти свойства экземплярам компонентов ContactCard и, по мере переноса данных из кода, который уже имеется в App , будем удалять соответствующие его фрагменты. В результате код компонента App будет выглядеть так:

Правда, одной только передачи свойств компоненту недостаточно для того, чтобы они были бы в нём использованы. Страница, которая будет сформирована вышеприведённым компонентом App , будет содержать четыре одинаковых карточки, данные которых заданы в коде компонента ContactCard , который пока не знает о том, что ему делать с переданными ему свойствами.

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

Поэтому сейчас пришло время поговорить о том, как компонент ContactCard может работать со свойствами, передаваемыми ему при создании его экземпляров.

Приступим к решению этой задачи, указав, при объявлении функции ContactCard , что она принимает параметр props . При этом код компонента будет выглядеть так:

На самом деле, этот параметр можно назвать как угодно, но в React принято называть его именно props , и те свойства, о которых мы тут говорим, часто называют просто «props».

Параметр props — это объект. Свойствами этого объекта являются свойства, переданные компоненту при создании его экземпляра. То есть, например, в нашем объекте props будет свойство props.name , содержащее имя кошки, переданное компоненту при создании его экземпляра. Кроме того, у него будут свойства props.imgUrl , props.phone , props.email . Для того чтобы в этом убедиться, добавим в начало функции ContactCard команду console.log(props) .

Это позволит вывести объект props , получаемый компонентом, в консоль.

Объект props в консоли

Тут можно видеть вывод четырёх объектов из ContactCard.js . Их именно столько из-за того, что мы создаём четыре экземпляра компонента ContactCard .

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

Что если мы попытаемся воспользоваться свойством props.imgUrl так:

На первый взгляд такая конструкция может сработать, но вспомним о том, что тут нам нужно использовать сущность из JavaScript в JSX-коде. О том, как это делается, мы говорили на одном из предыдущих занятий. А именно, в нашем случае свойство объекта нужно заключить в фигурные скобки:

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

Обратите внимание на то, что в полях для вывода телефона и адреса электронной почты мы оставили тексты Phone: и Email: с пробелами, следующими за ними, так как эти тексты используются во всех компонентах. Если теперь взглянуть на страницу приложения, то можно заметить, что она содержит четыре разных карточки.

Страница, сформированная с использованием универсального компонента

Наш компонент принимает всего четыре свойства. Что если некоему компоненту нужно будет, например, передать 50 свойств? Пожалуй, передавать каждое такое свойство отдельной строкой, как это сделано в компоненте App , будет неудобно. В таких случаях можно воспользоваться другим способом передачи свойств компонентам. Он заключается в том, что, при создании экземпляра компонента, ему передаётся не список свойств, а объект со свойствами. Вот как это может выглядеть на примере первого компонента:

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

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

Нарушение правильной работы приложения

Как это можно это исправить? Для того чтобы в этом разобраться, полезно будет проанализировать происходящее с помощью команды console.log(props) .

Анализ объекта props

Как видно, объект props первого компонента отличается от такого же объекта второго и следующих компонентов.

В компоненте ContactCard мы пользуемся объектом props исходя из предположения о том, что у него есть свойства name , imgUrl и прочие подобные. Здесь же первый компонент получает лишь одно свойство — contact . Это приводит к тому, что у объекта props оказывается лишь одно свойство — contact , являющееся объектом, а в коде компонента работа с подобной структурой не предусмотрена.

Перевести наш компонент на модель использования лишь одного свойства-объекта contact , содержащего другие свойства, довольно просто. Для этого, например, для доступа к свойству name , достаточно воспользоваться конструкцией вида props.contact.name в коде компонента. Аналогичные конструкции позволяют правильно работать с другими нужными нам свойствами.

Переработаем код компонента с учётом передачи ему единственного свойства-объекта contact , содержащего другие свойства:

Первый компонент теперь должен будет выводиться нормально, но мы этого, на данном этапе работы над проектом, не увидим, так как система сообщит нам о множестве ошибок, связанных с тем, что несколько экземпляров компонента ContactCard , создаваемые в компоненте App , не получают свойство-объект contact . При выполнении кода это свойство будет иметь значение undefined . В результате производится попытка обратиться к некоему свойству значения undefined , что и приводит к возникновению ошибки. Исправим это, переработав код компонента App , ответственный за формирование компонентов ContactCard :

Топ-пост этого месяца:  Как исправить проблему font-weight в состоянии hover

Теперь страница приложения будет выглядеть так же, как раньше.

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

Итоги

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

14 февраля 2020 г. 17:11

Если вам понравилась эта статья поделитесь ею с друзьями, тем самым вы помогаете нам развиваться и добавлять всё больше интересного и полезного контента!

Все фундаментальные принципы React.js, собранные в одной статье

В прошлом году я написал небольшую книгу об изучении React.js, которая заняла примерно 100 страниц. В этом году я собираюсь бросить вызов самому себе и сжать ее до размера статьи.

В этой статье не рассматривается, что такое React, или почему вы должны его изучить. Вместо этого дается практическое введение в основы React.js для тех, кто уже знаком с JavaScript и знает основы DOM API.

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

Принцип № 1: Компоненты — самая важная часть React

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

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

Компонент React — в его простейшей форме — это обычная функция JavaScript:

Фигурные скобки, используемые для метки кнопки будут объяснены ниже. Сейчас о них не стоит беспокоиться. ReactDOM также будет объяснен позже.

Второй аргумент для ReactDOM.render — это элемент DOM, который React собирается захватить и контролировать. В jsComplete REPL вы для этого просто можете использовать специальную переменную mountNode.

Обратите внимание на пример 1:

  • Название компонента начинается с заглавной буквы. Это необходимо, так как мы будем иметь дело с сочетанием элементов HTML и элементов React. Названия в нижнем регистре зарезервированы для элементов HTML. На самом деле, попробуйте назвать компонент React просто «button». ReactDOM проигнорирует функцию и отобразит обычную пустую кнопку HTML.
  • Каждый компонент получает список атрибутов, как и HTML-элементы. В React этот список называется props. С функциональным компонентом вы можете назвать этот список как угодно.
  • Функция render принимает что-то, что выглядит как HTML, но при этом помещено в JavaScript. Это не JavaScript и не HTML, и это даже не React.js. Но при этом это что-то настолько популярно, что стало стандартным в приложениях React. Это называется JSX, и это расширение JavaScript. Попробуйте вернуть любой другой элемент HTML внутри указанной выше функции и убедитесь в их поддержке (например, верните элемент ввода текста input).

Принцип № 2: Что такое JSX (What the flux is JSX)?

Пример 1 может быть записан в чистом React.js без JSX следующим образом:

Функция createElement является основной функцией верхнего уровня в React API. Это 1 из 7 функций на этом уровне, которые вам нужно изучить.

Подобно тому, как сам DOM содержит функцию document.createElement для создания элемента, с указанным именем тега, функция React createElement представляет собой функцию более высокого уровня, которая может делать то, что делает document.createElement, но при этом эта функция также может быть использована для создания элемента для представления компонента React.

В отличие от document.createElement, createElement React принимает неограниченное количество аргументов после второго аргумента, для представления дочерних элементов создаваемого элемента. Таким образом createElement фактически создает дерево.

Обратите внимание на пример 3:

  • InputForm не является компонентом React. Это всего лишь элемент React. Вот почему мы использовали InputForm, а не в вызове ReactDOM.render.
  • В функцию React.createElement было передано еще несколько аргументов после первых двух. Её список аргументов, начиная с третьего, содержит список дочерних элементов для создаваемого элемента.
  • Нам удалось вложить вызовы React.createElement, потому что это все JavaScript.
  • Второй аргумент React.createElement может быть null или пустым объектом, если для элемента не нужны атрибуты или свойства.
  • Мы можем смешивать HTML-элемент с компонентами React. Вы можете думать о элементах HTML как о встроенных компонентах React.
  • React API пытается быть как можно ближе к DOM API, поэтому мы используем >Код выше — это то, что браузер понимает, когда вы подключаете библиотеку React. Браузер не работает с JSX. Тем не менее, мы, люди, хотим видеть и работать с HTML вместо этих вызовов createElement (представьте себе создание веб-сайта с помощью только document.createElement). Вот почему был создан JSX. Вместо того, чтобы написать форму выше вызывая React.createElement, мы можем написать ее используя синтаксис, очень похожий на HTML:

Обратите внимание на следующее:

    Это не HTML, так как мы все еще используем >То, что мы написали выше (пример 4), — это JSX. Тем не менее, в браузере мы используем скомпилированную версию (пример 3). Чтобы пример 4 заработал, нам нужно использовать препроцессор для преобразования версии JSX в версию React.createElement.

JSX — это компромисс, который позволяет нам разрабатывать компоненты React используя HTML-подобный синтаксис, что довольно неплохо.

Слово «Flux» в заголовке выше было выбрано для рифмы, но это также название очень популярной архитектуры приложений, популяризированной Facebook. Самой известной реализацией которой является Redux. Flux идеально подходит для реактивной модели React.

JSX, кстати, может использоваться сам по себе. Это не часть React.

Принцип № 3: Вы можете использовать выражения JavaScript в любом месте JSX

Внутри секции JSX вы можете использовать любое выражение JavaScript в паре фигурных скобок.

Любое выражение JavaScript может быть помещено внутрь этих фигурных скобок. Это эквивалентно синтаксису интерполяции $<> в шаблонах JavaScript.

При использовании JSX есть одно ограничение. Внутри JSX можно использовать только выражения. Так, например, вы не можете использовать оператор if, но можете использовать тернарное выражение.

Переменные JavaScript также являются выражениями, поэтому, когда компонент получает список свойств (компонент RandomValue их не использует, свойства являются необязательными), вы можете использовать эти свойства внутри фигурных скобок. Мы использовали их в компоненте Button (пример 1).

Объекты JavaScript также являются выражениями. Иногда мы используем объект JavaScript внутри фигурных скобок, что выглядит как двойные фигурные скобки, но в действительности это просто объект внутри фигурных скобок. Один из вариантов использования — это передача объекта со стилями CSS в специальный атрибут style в React:

Обратите внимание на то, как я использовал деструктуризацию для получения message из параметра props. Это JavaScript. Также обратите внимание, что атрибут style является специальным (опять же, это не HTML). Мы используем объект как значение атрибута style. Этот объект определяет стили, как будто мы делаем это используя JavaScript (потому что так и есть).

Вы даже можете использовать элемент React внутри JSX, потому что это тоже выражение. Помните, что элемент React является вызовом функции:

Компонент MaybeError будет отображать компонент ErrorDisplay, если в него передается не пустая строка errorMessage и пустой div в противном случае. React рассматривает , , и действительными дочерними элементами, которые ничего не отображают.

Вы также можете использовать все функциональные методы JavaScript для коллекций (map, reduce, filter, concat и т. д.) внутри JSX. Опять же, потому что они возвращают выражения:

Обратите внимание на то, как я задал для свойства value значение по умолчанию, потому что это всего лишь JavaScript. Обратите внимание, что я вывел выражение массива внутри div. Для React это естественно. Он разместит каждое удвоенное значение в текстовом узле.

Принцип № 4: Вы можете разрабатывать компоненты React используя классы JavaScript

Простые функциональные компоненты отлично подходят для простых нужд, но иногда нам нужно больше. React поддерживает создание компонент с помощью синтаксиса class JavaScript. Вот компонент Button (в примере 1), написанный с помощью синтаксиса класса:

Синтаксис class прост. Определите класс, который расширяет React.Component (еще кое-что, что нужно изучить). Класс определяет единственную функцию render(), и эта функция возвращает объект виртуального DOM. Каждый раз, когда мы используем компонент на основе класса Button (например, ), React будет создавать экземпляр объекта этого компонента на основе класса и использовать этот объект в дереве DOM.

Именно по этой причине мы использовали this.props.label внутри JSX в функции render, поскольку каждый компонент получает специальный экземпляр, называемый props, содержащий все значения, переданные этому компоненту при его создании.

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

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

Несколько замечаний, касаемо примера 11:

  • Функция handleClick записывается с использованием нового синтаксиса стрелочной функции в JavaScript. Данный синтаксис все еще находится в stage-2, но по многим причинам это лучший способ доступа к экземпляру, смонтированному компонентом. Но вам нужно использовать такой компилятор, как Babel, чтобы заставить код выше работать. JsComplete REPL имеет предварительно настроенную конфигурацию и поэтому все примеры в данной статье работоспособны.
  • Мы также определили переменную экземпляра clickCounter, используя тот же синтаксис класса.
  • Когда мы указали функцию handleClick как значение специального атрибута onClick React, мы не вызвали ее. Мы передали ссылку на функцию handleClick. Вызов функции на этом уровне является одной из наиболее распространенных ошибок при работе с React.

Принцип № 5: События в действии: два важных отличия

При обработке событий внутри элементов React необходимо ясно понимать, что:

  • Все атрибуты элементов React (включая события) называются с помощью camelCase, а не в нижнем регистре. Это onClick, а не onclick.
  • Мы передаем фактическую ссылку на функцию JavaScript как обработчик события, а не строку. Это onClick = , а не onClick = “handleClick”.

React обертывает объект события DOM в собственный объект (SyntheticEvent), чтобы оптимизировать производительность обработки событий. Но внутри обработчика событий мы все равно можем получить доступ ко всем методам, доступным в объекте события DOM. React передает обернутый объект события для каждого вызова обработчика. Например, чтобы предотвратить отправку формы по умолчанию, вы можете сделать следующее:

Принцип №6: У каждого компонента React есть история

Следующее относится только к компоненту класса (к тем компонентам, которые расширяют React.Component). Функциональные компоненты имеют немного другую историю.

  1. Сначала мы определяем шаблон для React для создания элементов из компонента.
  2. Затем мы указываем React где будем его использовать. Например, внутри вызова функции render другого компонента или с помощью ReactDOM.render.
  3. Затем React создает экземпляр элемента и передает ему набор props, к которым мы можем получить доступ с помощью this.props. Эти props — это то, что мы передали на шаге 2.
  4. Поскольку это все JavaScript, то будет вызван метод конструктора (если он определен). Это первый метод из тех, что мы называем методами жизненного цикла компонентов.
  5. Затем React обрабатывает результат вызова функции render (получает виртуальный узел DOM).
  6. Поскольку это первый раз, когда React выполняет рендеринг элемента, React будет взаимодействовать с браузером (от нашего имени, используя DOM API), чтобы отобразить в нем элемент. Этот процесс широко известен как монтирование.
  7. Затем React вызывает другой метод жизненного цикла, называемый componentD >componentWillUnmount.
  8. Состояние любого смонтированного элемента может измениться. Родитель этого элемента может быть повторно отрисован. Также смонтированный элемент может получить другой набор props. И здесь начинается магия React и наступает именно тот момент, когда React нам так необходим! Честно говоря, до этого он нам особо и не был нужен.
  9. История этого компонента не заканчивается, но прежде чем продолжить, нам нужно понять, что же это за состояние, о котором я говорю.

Принцип № 7: React компоненты могут иметь внутреннее состояние

Следующее также применимо только к компонентам классам. Упоминал ли я, что некоторые люди называют компоненты только для отображения “глупыми”?

Поле класса state является специальным в любом компоненте классе React. React контролирует состояние каждого компонента для изменений. Но для того, чтобы React сделал это эффективно, мы должны изменить поле состояния с помощью еще одной функции API React, которую нам нужно изучить, это this.setState:

Это самый важный пример для понимания. Он в основном подытожит ваши фундаментальные знания о React. После этого примера есть еще несколько мелочей, которые вам нужно изучить, но в основном для них достаточно ваших навыков JavaScript.

Давайте рассмотрим пример 13, начиная с полей класса. В данном классе есть два поля. Специальное поле state инициализируется объектом, который содержит clickCounter, который начинается с 0, и currentTimestamp, который начинается с new Date().

Второе свойство — это функция handleClick, которую мы передали в событие onClick для элемента кнопки внутри метода render. Метод handleClick изменяет состояние экземпляра компонента, используя setState. Обратите внимание на это.

Другое место, в котором мы изменяем состояние, находится внутри таймера, который мы запустили внутри метода жизненного цикла componentDidMount. Он тикает каждую секунду и выполняет другой вызов this.setState.

В методе рендеринга мы использовали два свойства, которые есть у нас в state. Для этого нет специального API.

Теперь обратите внимание, что мы обновили состояние, используя два разных способа:

  1. Передавая функцию, которая возвращает объект. Мы сделали это внутри функции handleClick.
  2. Передавая обычный объект. Мы сделали это внутри функции обратного вызова, передаваемой в setInterval.

Оба способа приемлемы, но первый предпочтительнее, когда вы одновременно читаете и записываете состояние (что мы и делаем). Внутри функции обратного вызова мы только записываем в state и не читаем его. Если вы сомневаетесь, всегда используйте первый способ. Это безопаснее с условием гонки, потому что setState на самом деле является асинхронным методом.

Как мы обновляем состояние? Мы передаем объект с новым значением того, что хотим обновить. Обратите внимание, что в обоих вызовах setState мы передаем только одно свойство из поля состояния, а не оба. Это вполне нормально, потому что setState фактически объединяет то, что вы передаете (возвращаемое значение функции), с существующим состоянием. Поэтому, не указывая свойство при вызове setState, мы показываем, что не хотим изменять это свойство (и не удаляем его).

Принцип № 8: React всегда наготове

React получил свое название от того, что он реагирует на изменения состояния (хоть и не реактивно, но по графику). Была шутка, что React должен был быть назван Schedule!

Однако то, что мы наблюдаем невооруженным глазом при обновлении состояния любого компонента, — это то, что React реагирует на это обновление и автоматически отражает обновление в DOM браузера (при необходимости).

Думайте о том, что входными данными для функции render являются:

  • props, которые передаются родителем;
  • внутреннее состояние, которое может быть обновлено в любое время;

Когда входные данные функции render меняются, ее результат также может поменяться.

React ведет запись истории рендеринга, и когда он видит, что один рендер отличается от предыдущего, он рассчитывает разницу между ними и эффективно переводит разницу в фактические операции DOM API, которые затем будет выполнены в DOM.

Принцип № 9: React — ваш агент

Вы можете думать о React как об агенте, которого вы наняли, чтобы общаться с браузером. В качестве примера возьмем текущую метку времени. Вместо того, чтобы нам вручную переходить в браузер и вызывать операции DOM API, для того, чтобы каждый раз находить и обновлять элемент временной метки p#timestamp, мы просто изменили свойство в состоянии компонента, и React выполнил свою работу по общению с браузером от нашего имени. Я считаю, что это истинная причина популярности React. Нам не нравится разговаривать с браузером (и так много диалектов языка DOM, на котором он говорит), и React бесплатно вызвался вести переговоры за нас!

Принцип № 10: У каждого компонента React есть история (часть 2)

Теперь, когда мы знаем о состоянии компонента и как при изменении этого состояния происходит какая-то магия, давайте изучим последние несколько концепций.

  1. Компоненту может понадобится повторная отрисовка, когда его состояние будет обновлено или когда его родитель решает изменить props, которые он передал компоненту.
  2. Если происходит последнее, React вызывает другой метод жизненного цикла, componentWillReceiveProps.
  3. Если объект состояния или переданные props изменены, React должен принять важное решение. Должен ли компонент обновляться в DOM? Вот почему он вызывает другой важный метод жизненного цикла, shouldComponentUpdate. Этот метод по сути является вопросом, поэтому, если вам нужно самостоятельно настроить либо оптимизировать процесс отрисовки, вы должны ответить на этот вопрос, вернув либо true, либо false.
  4. Если метод shouldComponentUpdate не объявлен, React по умолчанию делает очень умную вещь, которая, на самом деле, достаточно хороша в большинстве ситуаций.
  5. Во-первых, React вызывает другой метод жизненного цикла, componentWillUpdate. Затем React рассчитает новое отображение компонента и сравнивает его с последним.
  6. Если результат точно такой же, React ничего не делает (нет необходимости разговаривать с браузером).
  7. Если есть разница, React переносит эту разницу в браузер, как мы видели раньше.
  8. В любом случае, поскольку процесс обновления произошел (даже если результат рендеринга был точно таким же), React вызывает последний метод жизненного цикла, componentD >Определять методы жизненного цикла необязательно. Если вы не делаете ничего особенного, то вы можете создавать полноценные приложения и без них. Они очень удобны для анализа того, что происходит в приложении, и для дальнейшей оптимизации производительности обновлений React.

Всё. Верьте или нет, но с тем, что вы изучили выше (или с его частью), вы уже можете начать создавать интересные приложения React. Если вы жаждете большего, ознакомьтесь с инструкцией по началу работы с React.js в Pluralsight.

Также для лучшего понимания темы я хотел бы порекомендовать книгу Learning React от Alex and Eve!

Подробное руководство по React.js в 2020 году

Эта статья была впервые опубликована в 2015 году, на данный момент она дополнена под версию React 16.3 и ее особенности.

Компоненты (Components) — «строительные блоки» в React. Если исходить из контекста Angular, у компонентов много общего с Directives. Если вы используете другой контекст, то это, по существу, виджеты или модули.

Вы можете думать о компонентах как о коллекции HTML, CSS, JS и некоторых «внутренних данных», специфичных для этого компонента. Мне нравится сравнение компонентов с Kolaches в веб. В них есть все, что нужно, запакованное в восхитительный компонуемый сверток.

Компоненты определяются на «чистом» (pure) JavaScript или они могут быть определены на том, что команда React называет “JSX”. Если вы решите использовать JSX (который, вы, вероятнее всего, будете использовать, и это стандартно — мы также будем его использовать для нашего туториала), вам понадобится какой-то этап компиляции, чтобы преобразовать JSX в JavaScript. Но об этом мы поговорим позже.

Что делает React настолько удобным для создания пользовательских интерфейсов (UI), так это то, что данные могут быть получены либо из родительского компонента, либо содержатся в самом компоненте. Прежде чем перейти к коду, давайте удостоверимся, что у нас есть понимание уровня компонентов на уровне высшего порядка.

Выше представлено изображение моего профиля Twitter. Если мы собираемся воссоздать эту страницу на React, мы разделили бы различные секции на разные компоненты (они выделены). Обратите внимание, что компоненты могут иметь вложенные компоненты внутри себя.

Мы могли бы назвать компонент слева (розовый) UserInfo . Внутри UserInfo компонента у нас есть еще один компонент (оранжевый), который мы могли бы назвать UserImages -компонентом.

Путь, по которому «работают» эти родительско-дочерние отношения — это наш UserInfo -компонент, или родительский компонент, в котором «живет» «состояние» (“state”) данных для него самого (UserInfo), так и для дочернего компонента UserImages .

Если мы хотим использовать какую-то часть данных родительского компонента в дочернем компоненте, то мы передадим эти данные дочернему компоненту в качестве атрибута.

В этом примере мы передаем UserImages-компоненту все изображения, которые есть у пользователя (которые в настоящее время «живут» в UserInfo -компоненте).

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

Эта иерархия parent / child делает управление нашими данными достаточно простым, потому что мы точно знаем, где находятся наши данные и мы не должны манипулировать ими в другом месте.

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

Я знаю, что это может выглядеть как «чересчур много», но вскоре вы увидите, насколько фундаментально важна каждая часть для создания надежных веб-приложений на React (и я также не шучу, когда я говорю, что хочу, чтобы это было «всесторонним» или исчерпывающим руководством).

На этом этапе вы должны понимать на «очень высоком уровне», как работает React. Теперь давайте перейдем к коду.

Создание первого компонента (JSX, Virtual DOM, render, ReactDOM.render)

Продолжим и напишем наш первый компонент на React.

Чтобы создать компонент на React, будем использовать ES6-класс. Если вы не знакомы с Классами, вы можете продолжить чтение, или узнать о них больше из других источников. (например, здесь — прим.переводчика)

Обратите внимание, что единственный метод в нашем классе — это render . Он является обязательным.

Причина — визуализация (render), описывающая пользовательский интерфейс (UI) нашего компонента. Таким образом, в этом примере текст, который будет отображаться на экране, где «рендерится» этот компонент, — Hello World!

Теперь изучим, что делает ReactDOM.

ReactDOM.render принимает два аргумента. Первый — компонент, который нужно отобразить, а второй — DOM-узел, где необходимо отобразить компонент.

Обратите внимание, мы используем ReactDOM.render , а не React.render . Это изменение в версии React.14, оно произведено, чтобы сделать React более «модульным». Это важно, если вы предполагаете, что React может отображать больше, чем просто DOM-элемент.

В примере выше мы просим React взять наш компонент HelloWorld и выполнить его render в элементе с ID root .

Из-за родительских / дочерних отношений React, о которых мы говорили ранее, обычно использовать ReactDOM.render потребуется только единожды, потому что рендер «самого» родительского компонента уже предполагает отображение всех его вложенных дочерних компонентов.

Теперь на этой стадии вы можете почувствовать немного странное «бросание» «HTML» в свой JavaScript. С тех пор, как вы начали изучать веб-разработку, вам сказали, что вы должны оставить свою логику вне представления, то есть сохранить ваш JavaScript, не связанный с вашим HTML.

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

«HTML», который вы пишете в методе render, на самом деле не HTML, это то, что в React называется «JSX». JSX просто позволяет нам писать HTML-подобный синтаксис, который в конечном итоге преобразуется в легковесные объекты JavaScript. После чего уже React может принимать эти объекты JavaScript и от них формировать «виртуальный DOM» или представление JavaScript реального DOM («виртуальный DOM» — «легковесная копия реального DOM» — прим. переводчика). Это создает ситуацию с выигрышем, когда вы получаете доступность шаблонов с мощью JavaScript.

В примере ниже то, во что в итоге будет скомпилирован ваш JSX.

Теперь вы можете отказаться от фазы преобразования JSX -> JS и написать свои компоненты на React, например, как в коде выше. Но, как вы можете себе представить, это было бы довольно сложно. Я не знаю никого, кто не использует JSX. Для получения дополнительной информации о компиляции JSX посмотрите статьи на тему React Elements vs React Components.

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

Причина, по которой команда React пошла этим путем, в том, что так как виртуальный DOM — это представление реального DOM, React может отслеживать разницу между актуальной виртуальной копией DOM, (вычисленной после изменений данных), и предыдущей, (вычисляется перед изменениями данных). Затем React изолирует изменения между старым и новым виртуальным DOM, после чего обновляет реальный DOM с необходимыми изменениями.

В более «дилетантских» выражениях, поскольку манипулирование реальным DOM происходит медленно («является более дорогостоящей операцией» — прим. переводчика), React способен минимизировать манипуляции с реальным DOM, отслеживая виртуальную копию DOM и обновляя реальный DOM только при необходимости и только с нужными изменениями.

Как правило, UI имеет множество состояний, затрудняющих управление состоянием в целом. Посредством ре-рендера виртуального DOM каждый раз, когда происходит какое-либо изменение состояния, React действительно упрощает размышления о том, в каком состоянии находится ваше приложение.

Процесс выглядит примерно так:

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

Поскольку это процесс преобразования от JSX к JS, необходимо настроить какую-то фазу трансформации во время разработки.

Во второй части я расскажу о Webpack и Babel для этого преобразования.

Давайте посмотрим на наш чек-лист «Самых важных частей React» и разберемся, где мы сейчас:

Мы идем в хорошем темпе. Все, что выделено «галочкой» — это то, что мы уже прошли, и вы сможете, по крайней мере, объяснить, как конкретно эти компоненты вписываются в экосистему React.

Добавление состояния к компоненту (state)

Далее по списку state . Ранее мы говорили о том, как сложно управлять UI, потому что они обычно имеют множество разных состояний. Это случай, когда React действительно начинает «светиться».

Каждый компонент имеет возможность управлять своим собственным состоянием (state) и передавать его дочерним компонентам, если необходимо.

Возвращаясь к примеру Twitter, UserInfo -компонент, (выделенный розовым цветом), отвечает за управление состоянием (или данными) информации пользователя.

Если другому компоненту тоже нужно это состояние / данные, но это состояние не было прямым дочерним UserInfo , тогда вы создали бы другой компонент, который был бы прямым родителем UserInfo и другого компонента (или обоих компонентов, которым требуется это состояние). Затем вы «прокинете» состояние вниз в качестве props в дочерние компоненты. Другими словами, у вас есть мульти-компонентная иерархия, где общий родительский компонент должен управлять состоянием и передавать его дочерним компонентам через props.

Рассмотрим примерный компонент, который использует свой state:

В этом примере мы использовали новый синтаксис. Первое, что вы заметите, — это метод конструктора. Из определения выше, метод конструктора — «способ установки состояния компонента» (начального состояния — прим.переводчика). Другими словами, любые данные, которые вы помещаете в this.state внутри конструктора, будут частью состояния этого компонента.

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

Последнее о чем можно поговорить про state в том, что нашему компоненту нужна возможность изменять собственное внутреннее состояние. Мы делаем это с помощью метода, который называется setState. Помните ранее, когда мы говорили о ре-рендеринге виртуального DOM при каждом изменении данных?

Сигнал об уведомлении нашего приложения о том, что некоторые данные изменились → Ре-рендер виртуального DOM → Разница (diff) между предыдущей виртуальной копией DOM с актуальной → Обновление только реального DOM с необходимыми изменениями.

Этот «сигнал об уведомлении нашего приложения о том, что некоторые данные изменились» на самом деле просто setState. Всякий раз, когда вызывается setState, виртуальный DOM повторно ре-рендерится, выполняется алгоритм «разницы», а реальный DOM обновляется с необходимыми изменениями.

Примечание: когда мы добавляем setState в приведенный ниже код, мы также представим несколько событий, которые есть в нашем списке. Одним ударом, сразу двух зайцев.

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

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

Когда вызывается handleChange , он будет вызывать setState , чтобы изменить наш username на значение, которое было введено в поле ввода (e.target.value) (предпочтительнее использовать e.currentTarget.value — прим.переводчика).

Помните, всякий раз, когда вызывается setState , React создает новый виртуальный DOM, выполняет «diff», а затем обновляет реальный DOM.

Теперь давайте посмотрим на наш render-метод. Мы добавили новую строку, содержащую поле ввода. Тип поля ввода, очевидно, будет text . Значение будет значением нашего username (имя пользователя), которое изначально было определено в конструкторе и будет обновлено в методе handleChange .

Обратите внимание, что есть новый атрибут, с которым вы, возможно, разньше не сталкивались — это onChange .

Атрибут onChange является «вещью из React», и он будет вызывать любой метод, который вы указываете, каждый раз, когда изменяется значение в поле ввода — в этом случае указанным нами методом был handleChange . (по аналогии с onchange в нативном javascript — прим.переводчика)

Процесс для кода выше будет выглядеть примерно так:

Пользователь вводит информацию в поле ввода (текст инпут) → вызывается handleChange → состояние нашего компонента меняется на новое значение → React повторно отображается виртуальную DOM → React считывает изменения → реальный DOM обновляется.

Позже, когда мы рассмотрим props, мы увидим несколько более сложных вариантов использования состояния.

А пока, мы идем дальше! Если вы не можете объяснить то, что выделено «галочкой», прочитайте этот раздел еще раз.

Один совет по ДЕЙСТВИТЕЛЬНОМУ изучению React: не позволяйте себе пассивно читать, давая себе ложное чувство понимания материала (почему только React? Это работает везде — прим.переводчика).

Перейдите в песочницу CodeSandbox и попробуйте воссоздать примеры выше (или сделайте свои компоненты), не подглядывая в туториал. Это единственный способ начать обучение React. Это касается и этого урока, и следующего.

Получение state от родительского компонента (props, propTypes, getDefaultProps)

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

Это позволяет архитектуре React оставаться довольно простой. Управляйте state в высшем родительском компоненте, который нуждается в использовании специфических данных и, если у него есть потомок, которому также необходимы эти данные, «прокиньте» данные в качестве props-аргументов.

Вот очень простой пример использования props.

Обратите внимание, что в строке 9 мы имеем параметр name со значением «Tyler». Теперь в нашем компоненте мы можем использовать , чтобы получить «Tyler».

Давайте рассмотрим более продвинутый пример. Теперь у нас будет два компонента. Один — родитель, другой — потомок. Родитель должен отслеживать состояние и передавать часть этого состояния дальше до ребенка в качестве props.

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

В этом компоненте не так много нового. У нас есть изначальное состояние (initial state, задано в конструкторе) и мы передаем его часть другому компоненту.

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

Помните, что код, который возвращает метод render — это представление того, как должен выглядеть реальный DOM. Если вы не знакомы с Array.prototype.map, этот код может показаться вам немного странным. Все, что делает метод .map — создает новый массив, вызывает коллбек для каждого элемента массива и заполняет новый массив результатом вызова функции-коллбека для каждого элемента.

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

Что примечательно касательно .map, этот метод отлично вписывается в React (и идет «из коробки» в JavaScript). Таким образом, в нашем дочернем компоненте выше мы просто обернули имена в тэг
и сохраняем результат в переменной listItems.

Затем метод render возвращает неупорядоченный список ( ) со всеми нашими друзьями.

Рассмотрим еще пример, прежде чем закончим с props. Важно понимать, что везде, где есть данные, ими можно там же манипулировать. Это упрощает рассуждение о данных. Все методы getter / setter для определенной части данных всегда будут в том же компоненте, где были определены эти данные. Если вам нужно манипулировать какой-то частью данных вне того, где «живут» данные, вы передадите метод getter / setter в этот компонент в качестве props. Давайте посмотрим на такой пример.

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

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

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

Однако, поскольку мы придерживаемся правила манипулировать данными только из компонента, «которому не все равно», мы передали метод addFriend в наш компонент AddFriend в качестве props и мы вызываем его с new friend после вызова handleAddNew.

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

Прежде чем мы пойдем дальше, хочу рассказать об еще двух возможностях React в отношении props. Это propTypes и defaultProps. Здесь я не буду вдаваться в подробности, потому что они довольно просты.

prop-types позволяют контролировать наличие или типы определенных props, переданных дочернему компоненту. С помощью propTypes вы можете указать, что требуются определенные props или что props являются определенным типом.

Начиная с React.15, PropTypes больше не включается в пакет React. Вам нужно будет установить их отдельно, запустив npm install prop-types .

defaultProps позволяют указать значение по умолчанию (или бэкап) для определенных props только в том случае, если эти props никогда не передаются в компонент.

Я изменил наши компоненты и теперь, используя propTypes, мы ожидаем что свойство addFriend будет функцией и что оно (свойство) будет передано в компонент AddFriend. Также, используя defaultProps, мы указали, что если массив друзей не передается компоненту ShowList, он будет пустым по умолчанию.

Итак, мы на последнем участке первой части.

Давайте посмотрим, что у нас осталось по плану.

Мы близки к финалу!

Жизненный цикл компонента (Component LifeCycle)

У каждого компонента, который вы создаете, будут свои события жизненного цикла, которые могут быть полезны для разных манипуляций. Например, если мы хотим сделать запрос AJAX для первого рендера и получить (fetch) данные, в каком lifecycle-методе это лучше сделать? Или, если бы мы захотели запустить какую-то логику, когда props изменились, как мы это сделаем?

Различные события жизненного цикла — ответы на оба вопроса.

Рассмотрим их ниже.

componentDidMount — вызывается один раз после первого рендера. К этому моменту компонент уже есть в DOM. Если вам нужно обратиться к виртуальному DOM — к вашим услугам this.getDOMNode(). Так же это лучший метод жизненного цикла компонента для работы с запросами на сервер.

componentWillUnmount — этот метод жизненного цикла вызывается непосредственно перед тем, как компонент будет удален из DOM. Здесь вы можете произвести необходимую очистку.

getDerivedStateFromProps — иногда вам нужно обновить состояние вашего компонента на основе «пришедших» props. Это метод жизненного цикла, в котором это можно сделать. Он будет принимать props и state, а возвращаемый объект будет объединен с текущим состоянием.

Если вы дошли до этого момента, это отличная работа! Я надеюсь, что это руководство было полезно для вас и теперь вы лучше понимаете React.

Для получения более подробной информации обратитесь к курсу Tyler McGinis React Fundamentals.

React.js для продолжающих

Итак, вы изучили основы React.js и теперь не знаете, что делать дальше? В статье рассмотрены 5 интересных вещей, которые поднимут ваши навыки и знания React.js на новый уровень.

Жизненный цикл компонента

Самой важной для понимания концепцией в этой статье является жизненный цикл компонента. Её суть ясна из названия — она описывает жизнь компонента. Как и мы, компоненты рождаются, что-то делают во время своего пребывания на бренной земле (сервере), а потом умирают.

Однако жизненные этапы компонентов немного отличаются от наших. Вот как они выглядят:

Каждый раскрашенный горизонтальный прямоугольник отражает метод жизненного цикла (за исключением «React обновляет DOM и ссылки»). Столбцы отражают разные этапы жизни компонента.

Компонент может находиться только на одном этапе. Всё начинается с монтирования и продолжается обновлением. Компонент постоянно обновляется, пока не будет удалён из виртуального DOM. Затем компонент переходит на этап размонтирования и удаляется из DOM.

Helastel, удалённо, от 150 000 ₽

Методы жизненного цикла позволяют запускать код в определённые моменты жизни компонента или в ответ на какие-то изменения в ней.

Пройдёмся по каждому этапу жизни компонента и связанным методам.

Монтирование

Так как компоненты на основе классов являются классами (отсюда и название), первый запускаемый метод — это constructor() . Как правило, в constructor() мы инициализируем состояние компонента.

Затем компонент запускает getDerivedStateFromProps() . Опустим этот метод, так как он не очень полезный.

После этого наступает очередь метода render() , который возвращает JSX. Теперь React «монтируется» в DOM.

Наконец, запускается метод componentDidMount() . Здесь выполняются все асинхронные вызовы к базам данных или напрямую управляется DOM. Компонент рождён.

Обновление

Этот этап запускается при каждом изменении состояния или свойств. Как и при монтировании, вызывается метод getDerivedStateFromProps() , но в этот раз без constructor() .

Затем запускается shouldComponentUpdate() . Здесь можно сравнивать старые свойства или состояния с новым набором свойств или состояний. Можно указать, нужно ли заново отображать компонент, вернув true или false . Это позволит сделать приложение более эффективным за счёт уменьшения количества лишних отображений. Если shouldComponentUpdate() возвращает false , на этом этап обновлений завершается.

В противном случае React заново отобразится, а затем запускается getSnapshotBeforeUpdate() . Этот метод тоже не очень полезен. Далее React запускает componentDidUpdate() . Как и componentDidMount() , его можно использовать для асинхронных вызовов или управления DOM.

Размонтирование

Компонент прожил хорошую жизнь, однако всё хорошее рано или поздно кончается. Размонтирование — последний этап жизни компонента. При удалении компонента из DOM React запускает componentWillUnmount() прямо перед удалением. Этот метод используется для закрытия всех открытых соединений вроде веб-сокетов или тайм-аутов.

Другие методы жизненного цикла

Прежде чем мы перейдём к другой теме, давайте вскользь упомянем forceUpdate() и getDerivedStateFromError() .

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

С другой стороны, getDerivedStateFromError() — метод жизненного цикла, который не совсем является его частью. Если в компоненте возникает ошибка, запускается getDerivedStateFromError() и вы получаете возможность обновить состояние, чтобы показать, что произошла ошибка. Используйте этот метод почаще.

Следующий фрагмент кода с CodePen показывает этапы стадии монтирования:

Понимание жизненного цикла компонентов и методов React позволит поддерживать правильную передачу данных между компонентами и обрабатывать события в приложении.

Компоненты высшего порядка

Возможно, вы уже использовали компоненты высшего порядка (КВП). Например, функция Redux connection() возвращает КВП. Но что из себя представляют эти компоненты?

Из документации React:

Компонент высшего порядка — это функция, которая принимает компонент и возвращает новый компонент.

Возвращаясь к функции connect() , посмотрим на следующий фрагмент кода:

При вызове connect() мы получаем КВП, который можно использовать для того, чтобы обернуть компонент. Затем мы просто передаём наш компонент в КВП и начинаем использовать возвращаемый им компонент.

КВП позволяют нам абстрагировать общую для компонентов логику в один главный компонент.

КВП можно использовать при авторизации. Код для аутентификации можно написать в каждом компоненте, которому она нужна. В итоге размер кода быстро раздуется до неприличных размеров.

Вот как всё это может выглядеть без КВП:

Тонна повторяющегося кода и запутанная логика!

И вот как код преобразится с использованием КВП:

Вот CodePen со всем кодом.

Глядя на этот код можно понять, что компоненты могут оставаться очень простыми, даже, если будут производить аутентификацию. Компонент AuthWrapper содержит всю логику аутентификации. Всё, что он делает, — смотрит на свойство isLoggedIn и возвращает WrappedComponent или тег

в зависимости от присвоенного свойству значения.

Как видите, КВП очень полезны, так как позволяют повторно использовать код. Скоро мы к ним вернёмся.

Состояние и setState()

Большинство из вас скорее всего уже использовали состояния React, они были даже в примере с КВП. Однако важно понимать, что при смене состояния React запустит процесс повторного отображения компонента (если не указать иное в shouldComponentUpdate() ).

Поговорим о том, как можно изменить состояние. Единственный способ сделать это — использовать метод setState() . Он принимает объект и объединяет его с текущим состоянием. Помимо этого есть ещё несколько вещей, которые следует знать.

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

Взглянув на эту картинку можно увидеть, что мы сначала вызываем setState() , а затем console.log() . Новое значение переменной counter должно быть равно 1, однако выводится 0. Что если мы хотим получить доступ к новому состоянию после того, как setState() действительно обновит состояние?

Тут мы плавно переходим к следующей вещи, которую нужно знать о setState() — этот метод может принимать callback-функцию. Исправим наш код:

Отлично, всё работает, на этом можно закончить, да? Не совсем. На самом деле, в данном случае мы не используем setState() корректно. Вместо передачи объекта мы передадим методу функцию. Так обычно делается, когда для установки нового состояния используется текущее. Если это не ваш случай, то смело продолжайте передавать объект в setState() . Исправим код ещё раз:

Вот CodePen для этого примера.

В чём смысл передачи функции вместо объекта? Поскольку setState() асинхронный, полагаться на него при создании нового значения немного рискованно. Например, к моменту запуска одного setState() другой setState() мог уже обновить состояние. Передача функции в setState() даёт два преимущества:

  1. Это позволяет создавать статичную копию состояния, которое никогда не изменится само по себе.
  2. Это поместит вызовы setState() в очередь, поэтому они будут запускаться по порядку.

Посмотрим на следующий пример, в котором попытаемся увеличить счётчик на 2, используя два последовательных вызова setState() :

Сравните с кодом ниже:

На первом изображении обе функции setState() напрямую используют this.state.counter , который, как мы узнали ранее, останется со значением 0 после вызова первого setState() . Таким образом, конечное значение равно 1, а не 2, так обе функции setState() устанавливают значение счётчика равным 1.

На втором изображении мы передаём в setState() функцию, что гарантирует последовательный запуск обеих функций. Кроме этого, мы делаем снимок состояния, а не используем текущее, не обновлённое состояние. Теперь мы получили ожидаемый результат.

Вот и всё, что вам нужно знать о состояниях React.

Контекст

Контекст React — это глобальное состояние для компонентов.

API контекста React даёт возможность создавать глобальные объекты компонентов, которые будут доступны любому компоненту. Это позволяет обмениваться данными без необходимости передавать свойства по всему дереву DOM.

Как использовать контекст?

Сначала создадим объект контекста:

В документации React установка контекста в компоненте выглядит так:

Однако в CodePen (React 16.4.2) это не сработало. Вместо этого мы воспользуемся КВП, чтобы использовать контекст образом, похожим на тот, что рекомендует Дэн Абрамов.

Здесь мы оборачиваем компонент в компонент Context.Consumer и передаём в контекст в качестве свойства.

Теперь мы можем написать что-то такое:

И у нас будет доступ к foo из объекта контекста в свойствах.

А как сменить контекст? Это уже немного сложнее, однако мы можем ещё раз использовать КВП и получить что-то такое:

Сначала мы берём исходное состояние контекста — объект, переданный в React.createContext() — и используем его в качестве состояния компонента-обёртки. Затем мы определяем все методы, которые будем использовать для смены состояния. Наконец, оборачиваем наш компонент в компонент Context.Provider . Мы передаём состояние и функцию в свойство value . Теперь они будут в контексте у всех наследников, обёрнутых в компонент Context.Consumer .

Собираем всё воедино (КВП опущены для краткости):

Теперь у дочернего компонента есть доступ к глобальному контексту. У него есть возможность изменить значение атрибута foo в состоянии на baz .

CodePen со всем кодом по теме контекста.

Не пропускайте новостей React!

React активно развивается. Например, в React 16.3 некоторые методы жизненного цикла были упразднены, в React 16.6 появились асинхронные компоненты, а в React 16.7 появились хуки, цель которых — полностью заменить компоненты на основе классов. Следите за развитем React и растите вместе с ним!

Примеры на React. Быстрый старт в изучении React

React строится вокруг концепции компонентов. В отличие от таких фреймворков типа Angular и Ember которые используют двухстороннюю привязку данных для обновления HTML страницы. На мой взгляд, React более прост в освоении, чем Angular и Ember – он намного меньше и хорошо работает с jQuery и другими фреймворками. Он также очень быстрый, потому что он использует виртуальный DOM и синхронизирует только измененные части с основной страницы (доступ к DОМ по-прежнему является медленной часть современного веб-приложения). Однако, обратной стороной является то, что те вещи, которые легко могли бы быть сделаны с помощью привязки данных, занимают немного больше кода в React. В этом вы можете убедиться в приведенных ниже примерах.

Как начать использовать React

Для использования React, вам необходимо включить один файл JavaScript в вашем страницы. Facebook любезно предоставляет нам CDN, на который вы можете сослаться:

Размер файла browser.min.js превышает 1Mb, поэтому такое использование на продакшн строго не рекомендуется!

Это дает вам доступ к глобальному React-объекту, который содержит ряд полезных методов, некоторые из которых вы можете увидеть в наших примерах. Рекомендуемым способом написания реактивного веб-приложения является использование языка под названием JSX. Это немного расширенная версия JavaScript, которая позволяет инициализировать React-компоненты с помощью синтаксиса HTML непосредственно в коде. Этот код компилируется в JavaScript, перед тем как быть интерпретированным браузером. Но, достаточно говорить, давайте перейдем к примерам на React!

Таймер на React

Как я уже упоминал, приложение на React разбивается на блоки — компоненты. Они создаются путем вызова React.createClass() с объектом опций и методов. Каждый компонент имеет состояние (объект с данными) и каждый отвечает за свой собственной рендеринг — метод render() вызывается всякий раз, когда состояние изменяется. Вот пример создания простого таймера:

Таймер на React JS

Надпись с информацией будет выводиться в div с , так что не забудьте разместить его на вашей web-странице. Результат работы нашего примера вы можете посмотреть на странице Таймер на React.

Навигационное меню на React JS

Давайте посмотрим, как мы можем обработать событие click в React на примере создания меню навигации:

Обратите внимание на атрибут className, которого не существует в HTML. дело в том, что JSX — это JavaScript и такие атрибуты, как class и for неодобряются. Вместо них следует использовать className и htmlFor. Результат работы нашего примера вы можете посмотреть на странице Меню на React.

Мгновенный поиск

Как вам, должно быть, известно, больше всего на свете пользователи не любят долгое ожидание. Вот как можно сеализовать на React функционал для мгновенного поиска.

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

Результат работы нашего примера вы можете посмотреть на странице Мгновенный поиск на React JS.

Форма заказа на React

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

Основная проблема, возникающая при работе с несколькими компонентами, — это как реализовать обмен данными между ними. Можно передавать необходимые данные атрибутами при их инициализации. Это работает только в случае общения компонентов «от родительского к дочернему». Для общения в другом направлении можно передать один из методов родительского компонента в дочерний с помощью атрибута.

Результат работы нашего примера вы можете посмотреть на странице Форма заказа на React JS.

Работа с jQuery и AJAX

Этот пример покажет как вы можете объединить React с jQuery и как загружать результаты при через AJAX. В то время как фреймворки типа Angular имеют свои собственные подходы для работы с AJAX, React позволяет вам использовать те библиотеки которые вы хотите.

Обратите внимание: в нашем примере используется один и тот же компонент Picture для отображения списка со всеми изображениям и избранными. Такое неоднократное использование кода является одним из преимуществ React.

Результат работы нашего примера вы можете посмотреть на странице Работа с jQuery и AJAX вReact JS.

Style Gu >

Базовые правила

1) Определяйте один React компонент в одном файле.

2) Всегда используйте JSX синтаксис.

4) Не используйте React.createElement, если только вы не инициализируете приложение из не-JSX файла.

Название переменных и методов.
<>> (не selectFunc, select, handleSelect) onDrop=<()=><>> // Не используются сокращения value= <1>(не val) item= <1>(не itm) /> ><> а не fileRequest, fileFromBackend refreshIcon = () =><> а не iconRefresher closeMenu = () =>< // переменные boolean без is/has (в редких случаях допустимо) const done = items.length === 0; (не hasDone) const selected = items[1] === true (не isSelected) >>

Не используйте React.createClass. // bad const Listing = React.createClass(< . render() < return

Компоненты стоит создавать через класс React.Component или React.PureComponent только если у них есть внутреннее состояние (state), ссылки (refs) или требуется использование жизненного цикла (lifecycle).

Установка состояния компонента

Первоначальное состояние компонента устанавливаем в конструкторе. // bad class Example extends React.Component < state = < value: this.props.value >> // good class Example extends React.Component < constructor(props) < super(props); this.state = < value: props.value >> >

Вообще лучше избегать стейта компонента. Если вам требуется пересчитывать стейт при изменении props, то воспользуйтесь методом getDerivedStateFromProps. Если state всегда вычисляется как функция от props, то лучше вместо него воспользоваться мемоизацией.

Обновление состояния компонента

Смена состояния компонента происходит путем передачи в setState объекта, в случае если новый state опирается на текущий state, то используем функциональный setState. // bad class Example extends React.Component < handleChange = (event) => < const = event; // useless use of functional setState this.setState(() => ()) > > // good class Example extends React.Component < handleChange = (event) => < const = event; this.setState() > > // bad class Example extends React.Component < constructor(props) < super(props); this.state = < counter: 0 >> handleClick = () => < // multiple calls during the same cycle may be batched together this.setState() > > // good class Example extends React.Component < constructor(props) < super(props); this.state = < counter: 0 >> handleClick = () => < this.setState((state) =>()) > >

Именование

Используйте всегда файлы с расширением .jsx для React компонентов. Используйте hyphen-style для названия файла. Как правило, файлы содержат одну сущность. В таких случаях название файла должно соответствовать названию сущности. import * as React from ‘react’; . export class OverlayLayout extends React.Component < . render() < const = this.props; . > >

Используйте Индексные файлы (index.js) для экспорта открытых частей модуля. Называйте файлы исходя из сути содержимого, например: header.jsx, siderbar.sass, primary-button.jsx, overlay-layout.jsx. Общие названия допустимы на уровне абстрактных модулей/компонентов.

Не используйте сокращения в названиях функций. // bad function q() < // . stuff. >// good function query() < // ..stuff.. >

Используйте camelCase для объектов и функций. // bad const OBJEcttsssss = <>; const this_is_my_object = <>; function c() <> // good const thisIsMyObject = <>; function thisIsMyFunction() <>

Используйте PascalCase для конструкторов и классов. // bad function user(options) < this.name = options.name; >const bad = new user(< name: 'nope', >); // good , >);

Распространенные, устоявшиеся сокращения в именах должны быть в одном регистре. // bad import from ‘./containers/SmsContainer’; // bad const HttpRequests = [ // . ]; // good import from ‘./containers/sms-container’; // good const HTTPRequests = [ // . ];

Кавычки

Всегда используйте двойные кавычки («) для JSX аттрибутов, а одинарные (‘) для всего остального кода на Javascript. Обычные HTML атрибуты также как правило используют двойные кавычки вместо одинарных. Таким образом, JSX атрибуты следуют этой конвенции. // bad // good // bad // good

Пробелы

Всегда добавляйте один пробел в самозакрывающийся тэг. // bad // very bad // bad // good

Не отделяйте фигурные скобки от их содержимого пробелами. // bad // good

Свойства компонентов

Не используйте стандартные названия DOM-свойств для других целей. Ожидается, что свойства style и className используются только для одной цели. Если не следовать этому правилу в приложении, то его код становится менее читаемым и поддерживаемым, и может являться причиной дефектов. // bad // good

Используйте camelCase для именования свойств компонента. // bad // good

Используйте сокращенную запись для булевых свойств. // bad // good

Избегайте дублирование названий свойств и названия компонента. Например, для компонента ImagesList лучше использовать items, а не images.

Избегайте использования индексов массива как значение свойства key. Предпочтительнее будет уникальный идентификатор. // bad )> // good ( ))>

Всегда определяйте defaultProps для всех не обязательных свойств.

Ссылки (refs)

Всегда используйте в качестве значения ref поле, созданное с помощью React.createRef(). // bad // bad < this.myRef = ref; >> /> // good class MyComponent extends React.Component < myRef = React.createRef(); render() < return

Круглые скобки

Оборачивайте JSX тэги в круглые скобки, если они занимают более одной строки. // bad render() < return ; >// good render() < return ( ); >// good, when single line render() < const body =

Всегда используйте самозакрывающиеся тэги, если они не имеют потомков. // bad // good

Если у компонента свойства расположены на нескольких строках, закрывайте тэг на новой строке. // bad // good

Методы

Используйте стрелочные функции (arrow functions) для замыкания локальных переменных. function ItemList(props) < return (

    ( doSomethingWith(item.name, index)> /> ))>

); >

Чтобы обойтись без привязки this к обработчикам событий, определяйте их как свойства класса, где значением будет стрелочная (arrow) функция. // bad class extends React.Component < onClickDiv() < // do stuff >render() < return

Не используйте символ подчеркивания для частных (private) методов React компонента. // bad React.createClass(< _onClickSubmit() < // do stuff >, // other stuff >); // good class extends React.Component < onClickSubmit() < // do stuff >// other stuff > Подобный знак нижнего подчеркивания (_) используется в некоторых языках для указания метода, как частного (private). Но, в отличие от других языков программирования, у JavaScript не реализована подобная функциональность, все методы — public. И не смотря на использования префикса _, он не делает методы по-настоящему частными. Для более глубокого изучения данного вопроса изучите обсуждения #1024 и #490.

Хуки в React – это новая возможность, которая появилась в версии 16.8. Они позволяют использовать состояние и другие возможности компонентов React в рамках функционального программирования.

Программ-чистильщиков для Windows 10 существует достаточно много, но не все из них обрели популярность. Незаслуженно обойденным вниманием оказался и чистильщик Clean Space.

WAU Manager — бесплатный инструмент для получения максимально полного контроля над процессами обновления Windows.

С помощью объекта Proxy у разработчиков появилась возможность получить контроль над некоторыми внутренними операциями, которые ранее были скрыты «под капотом» движка javascript.

Изучаем JavaScript

Массивы как свойства компонентов react

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения

Сейчас данные о пунктах списка дел хранит TodoList в свойствах label и important

Это не совсем правильный подход. Задача списка дел — отображать данные, а получать и хранить их значения и важность лучше в основном файле проекта index.js в компоненте App. При таком подходе, если нам понадобится изменить список дел, не нужно будет искать его по всем файлам проекта, достаточно будет внести изменения в основной файл.

Мы создали массив todoDate, элементами его являются объекты с ключами label и important и добавили этот объект в качестве свойства компоненту TodoList.

Передать данные из в TodoList можно было бы так

Такой подход работающий, но наивный и не оптимальный. Перебирать массив по одному элементу не совсем правильно.
Оптимизируем код выше:

Можно ещё немного сократить код, использовав spread-оператор для объекта. Если имена свойств компонента совпадают с именами свойств объекта, нет необходимости перечислять их, достаточно использовать оператор расширения

В результате вот такая строка

превратится вот в такую

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

Топ-пост этого месяца:  Названы социальные ресурсы Рунета с самыми активными пользователями
Добавить комментарий