React программирование что это

Как работает React: подробное руководство

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Основным источником вдохновения для меня послужила эта замечательная статья.

Введение

Что здесь происходит?

Функция React.createElement создает объект на основе переданных ей аргументов. Не считая некоторой валидации, это все, что делает данная функция.

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

В данном случае children — это строка, но, как правило, значением этого свойства является массив элементов. Вот почему элементы — это деревья (tree) с точки зрения структуры.

Затем мы присваиваем узлу все пропы ( props ). В данном случае у нас имеется только заголовок ( title ).

Далее мы создаем узлы для дочерних элементов. В данном случае у нас имеется только один такой элемент — строка. Поэтому мы создаем текстовый узел.

Использование nodeValue вместо innerText позволит нам одинаково обрабатывать все элементы. Обратите внимание, что мы устанавливаем nodeValue так, как если бы строка имела props: < nodeValue: "Hello from MyReact!" >.

Функция createElement

Мы используем операторы spread для props и rest для children (поэтому children всегда будет массивом).

createElement(«section», null, «hello») вернет:

createElement(«section», < title: "hello" >, «hello», «world») вернет:

Комментарий /** @jsx MyReact.createElement */ сообщает Babel о нашем желании использовать собственную версию createElement для создания элементов.

Функция render

Создаем новый узел на основе типа элемента и добавляем его в контейнер.

Затем мы делаем тоже самое для каждого потомка узла рекурсивно.

И последнее, что нам нужно сделать, это присвоить узлу пропы элемента.

Самым простой способ запустить этот пример (и другие):

Конкурентный режим (Concurrent Mode)

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

В чем проблема этого рекурсивного вызова? (Представим, что вы проходите собеседование для устройства на работу в Facebook 😉 )

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

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

Подстраховаться на случай отсутствия поддержки requestIdleCallback можно так:

Подробнее о requestIdleCallback можно почитать здесь и здесь.

Волокно (Fiber)

Для организации правильного взаимодействия между единицами работы нам нужна подходящая структура данных. Одной из таких структур является fiber tree (условно можно перевести как «древесное волокно»).

У нас имеется одно волокно для каждого элемента и каждое волокно представляет собой единицу работы.

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

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Предположим, что мы хотим отрендерить такое дерево элементов:

Одной из задач этой структуры данных является упрощение определения следующей единицы работы. Вот почему каждое волокно имеет ссылки на первого потомка ( child ), сиблинга ( sibling ) и предка ( parent ).

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

Когда браузер будет готов, он запустит «колбек» workLoop и начнется обработка корневого узла.

Затем для каждого потомка создается волокно.

Наконец, мы определяем и возвращаем следующую единицу работы. Сначала мы возвращаем потомка. Если потомок отсутствует, возвращается сиблинг. Если сиблинга нет, поднимаемся к предку и возвращаем его сиблинга и т.д.

Этапы рендеринга и фиксации результатов (Commit)

В чем проблема этого блока кода? (Второй вопрос из 100 😉 )

Согласование (Reconcilation)

Здесь мы будем сравнивать старые волокна с новыми элементами.

Мы одновременно перебираем потомков старого волокна ( workingFiber.alternate ) и массив новых элементов для сравнения.

Для их сравнения мы используем тип:

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

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

Мы также добавляем в волокно новое свойство action (в React используется название effectTag ). Это свойство будет использоваться на стадии фиксации.

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

Поэтому нам нужен массив для узлов, подлежащих удалению.

Мы используем этот массив при фиксации результатов.

В функции commitWork заменяем parentNode.append(fiber.node) на следующее:

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

Если обработчик отсутствует или изменился, его нужно удалить.

Затем мы добавляем новые обработчики.

Функциональные компоненты (Functional Components)

Добавим поддержку функциональных компонентов.

Функциональные компоненты отличаются от обычных элементов следующим:

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

В функции updateHostComponent мы делаем тоже самое, что и раньше.

А в updateFunctionalComponent мы запускаем переданную функцию для получения дочерних элементов.

Логика согласования потомков остается прежней, нам не нужно ничего в ней изменять.

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

Хуки (Hooks)

Последнее, что нам осталось сделать, это добавить в функциональные компоненты состояние.

Здесь у нас имеется простой компонент счетчика. При клике по заголовку значение счетчика увеличивается на 1.

Обратите внимание, что мы используем MyReact.useState для получения и обновления значения счетчика.

Нам необходимо инициализировать некоторые глобальные переменные для хранения информации о хуках.

Сначала мы определяем рабочее волокно ( workingFiber ).

Затем мы добавляем массив hooks в волокно для того, чтобы иметь возможность вызывать useState несколько раз в одном компоненте. Также мы фиксируем индекс текущего хука.

При вызове useState мы проверяем, имеется ли у нас старый хук. Для этого мы заглядываем в свойство alternate волокна, используя индекс хука.

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

Затем мы добавляем новый хук в волокно, увеличиваем значение индекса на 1 и возвращаем состояние.

Мы помещаем эту операцию в очередь ( queue ) хука.

Затем мы повторяем логику функции render : новый workingRoot становится следующей единицей работы, что приводит к запуску новой стадии рендеринга.

Операции выполняются при следующем рендеринге компонента. Мы получаем все операции из очереди старого хука и применяем их по одной к состоянию хука. После этого мы возвращаем обновленное состояние.

Но прежде, чем мы закончим, внесем еще несколько мелких правок.

Запуск проекта с помощью Snowpack

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Инициализируем проект, находясь в корневой директории:

Настраиваем snowpack ( snowpack.config.json ):

Настраиваем babel ( babel.config.json ):

Определяем команду для запуска snowpack в package.json :

Запускаем проект в режиме для разработки:

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Заключение

Полезные ссылки для тех, кому, как и мне, всегда мало:

Надеюсь вам было интересно и вы не жалеете потраченного времени.

Источник

React.js для новичков в программировании: что это, как устроен и зачем нужен

Если стажёр или совсем зелёный джун попросят вас объяснить, что такое React.js, — просто покажите им эту статью.

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

OlyaSnow для Skillbox Media

В интернете полно руководств по React.js с названиями типа for dummies, for idiots — вроде бы для чайников. Но они по большей части негуманны и довольно сложны — человеку без знания JavaScript пользы не будет, только сильнее запутается и почувствует себя тем самым dummy. Поэтому мы решили максимально просто объяснить, что такое React.js, для чего он нужен, как попробовать и что понадобится для полноценной работы.

Что это ещё за новый тикток такой?

React.js — это JavaScript-библиотека от Facebook для удобной разработки интерфейсов, то есть внешней части сайтов и приложений, с которой взаимодействует пользователь.

Главная фишка React.js — компоненты и состояния.

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

Состояние — это вся информация об элементе, в том числе о его отображении. Например, состояние объекта «термометр» может описываться свойствами current_temperature, min и max.

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Фанат Free Software Foundation, использует Linux и недолюбливает Windows. Пишет истории про кодинг и программы на Python. Влюблён в Lisp, но пока что не умеет на нём программировать.

Переводим на понятный язык: что такое компоненты и состояния

Пока звучит немного абстрактно и сложно, но на деле всё гораздо проще. Потренируемся на Цукерберге: в конце концов, это его детище — ему и отвечать.

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

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

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

Посмотрите, как в зависимости от состояния меняется размер аватарки:

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Уже получилось три состояния, но это не предел — ведь внешний вид аватарки различается в мобильной и десктопной версии, в приложении для Android, iOS и так далее. Отметим, что аватарка практически везде будет вложенной — в составе более крупных компонентов React.js, таких как пост, шапка, боковая панель или меню.

В React.js есть собственные средства для управления состояниями, но на практике в средних и крупных проектах чаще используют Redux — сторонний менеджер состояний. Он удобнее и лучше масштабируется.

Зачем нужен React.js, если есть HTML, JavaScript и CSS

Никаких огородов. React.js — это всего лишь способ в удобном виде представить код JavaScript и HTML, сделать его повторяемым и наглядным. Компоненты React.js пишут на особом языке — JSX, который выглядит как смесь JavaScript и HTML. Вот пример кода на этом языке:

JSX-код — то, что кажется HTML-тегом

, на самом деле элемент JSX

Код JSX довольно наглядный, и, кстати, то, что похоже на HTML, — вовсе не HTML 🙂 Звучит галлюциногенно, но это просто синтаксис JSX.

Браузеру понимать JSX не нужно — код React.js транслируется в JavaScript, с которым знаком любой уважающий себя браузер. Для этого написанное на React.js приложение прогоняют, например, через Babel — специальную программу-транспайлер, которая переводит разные представления (то есть языки вроде JSX) в JavaScript-код.

JSX-код JavaScript-код после Babel

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

У React.js есть три мощных преимущества:

Источник

Учебник: введение в React

Данный учебник не предполагает каких-либо знаний React.

Перед тем как начнём

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

Учебник состоит из нескольких разделов:

Установка. Даст вам отправную точку, чтобы следовать учебнику.

Обзор. Познакомит вас с основами React: компонентами, свойствами и состоянием.

Завершение игры. Научит вас наиболее распространенным методам разработки в React.

Добавление Time Travel. Даст вам более глубокое понимание уникальных преимуществ React.

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

Что мы разрабатываем?

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

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

Предварительные требования

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

Установка

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

1-й вариант установки

Это самый быстрый способ начать работу!

Сначала откройте этот стартовый код в новой вкладке. Новая вкладка должна отображать пустую игровую доску в крестики-нолики и код React. В этом учебнике мы будем редактировать код React.

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

2-й вариант: локальная среда разработки

Это исключительно по желанию и совершенно не обязательно для данного учебника!

Необязательно: инструкции для разработки локально с помощью предпочитаемого вами текстового редактора.

Данная установка потребует больше времени и сил, но позволяет вам освоить учебник, используя предпочитаемый вами редактор (например WebStorm). Выполните следующие шаги:

Убедитесь, что у вас установлена последняя версия Node.js.

Удалите все файлы в папке src/ нового проекта.

Добавьте файл с именем index.css в папку src/ с этим кодом CSS.

Добавьте файл с именем index.js в папку src/ с этим кодом JS.

Добавьте следующие три строки в начало файла index.js в папке src/ :

Теперь, если вы запустите npm start в папке проекта и откроете http://localhost:3000 в браузере, вы должны увидеть пустое поле крестики-нолики.

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

Помогите, я застрял!

Обзор

Теперь, когда вы произвели всю необходимую установку, давайте познакомимся с React!

Что такое React?

В React есть несколько разных типов компонентов, но мы начнем с подклассов React.Component :

Cкоро мы перейдем к забавным XML-подобным тегам. Мы используем компоненты, чтобы сообщить React, что именно мы хотим видеть на экране. Когда наши данные изменятся, React будет эффективно обновлять и повторно отрисовывать наши компоненты.

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

Если вам интересно, createElement() более подробно описан в справочнике по API, но мы не будем пользоваться им в этом учебнике. Вместо него мы будем продолжать использовать JSX.

JSX включает в себя JavaScript. Вы можете поместить любые выражения JavaScript в фигурные скобки внутри JSX. Любой React элемент представляет собой объект JavaScript, который вы можете сохранить в переменной или передать куда-либо в своей программе.

Компонент ShoppingList выше отрисовывает только нативные компоненты DOM, такие как

Проверка стартового кода

Если вы собираетесь работать с учебником в своем браузере, откройте этот код в новой вкладке: стартовый код. Если вы собираетесь работать над учебником в локальной среде, откройте src/index.js в папке вашего проекта (вы уже коснулись этого файла во время установки).

Этот стартовый код является основой того, что мы строим. Мы предоставили стили CSS, так что вам нужно сосредоточиться только на изучении React и программировании игры в крестики-нолики.

Изучив код, вы заметите, что у нас есть три компонента React:

Передача данных с помощью props

В методе renderSquare компонента Board измените код, чтобы передать свойство с именем value в компонент Square :

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

После: вы должны увидеть число в каждом квадрате в отрисованном выводе.

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

Создание интерактивного компонента

Если мы сейчас нажмем на Square, то должны получить предупреждение в нашем браузере.

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

Следующим шагом мы хотим, чтобы компонент Square «запомнил», что на него щелкнули, и заполнил себя знаком « X ». Чтобы «запоминать» вещи, компоненты используют состояние.

Сначала мы добавим конструктор в класс для инициализации состояния:

Теперь мы изменим метод render компонента Square для отображения значения текущего состояния при нажатии:

Поместите атрибуты className и onClick в отдельные строки для лучшей читаемости.

Когда вы вызываете setState в компоненте, React автоматически обновляет и дочерние компоненты внутри него.

Инструменты разработчика

Расширение React Devtools для Chrome и Firefox позволяет вам просматривать дерево компонентов React с помощью инструментов разработчика в вашем браузере.

React программирование что это. Смотреть фото React программирование что это. Смотреть картинку React программирование что это. Картинка про React программирование что это. Фото React программирование что это

React DevTools позволяет вам проверять свойства и состояние ваших компонентов React.

После установки React DevTools вы можете щелкнуть правой кнопкой мыши по любому элементу на странице, нажать «Inspect», чтобы открыть инструменты разработчика. Вкладка React появится последней справа.

Однако обратите внимание, что необходимо сделать несколько дополнительных шагов, чтобы заставить его работать с CodePen:

Войдите или зарегистрируйтесь и подтвердите свой адрес электронной почты (необходим для предотвращения спама).

Нажмите кнопку «Fork».

Нажмите «Change View», а затем выберите «Debug mode».

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

Завершение игры

Теперь у нас есть основные строительные блоки для нашей игры в крестики-нолики. Чтобы завершить игру, нам необходимо чередовать размещение « X » и « O » на доске, а также нам нужен способ определить победителя.

Поднятие состояния вверх

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

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

В настоящее время метод renderSquare в Board выглядит следующим образом:

Мы разбиваем возвращаемый элемент на несколько строк для удобства чтения и добавляем скобки, чтобы JavaScript не вставлял точку с запятой после return ломая наш код.

Заменим this.state.value на this.props.value в методе render компонента Square

Заменим this.setState() на this.props.onClick() в методе render компонента Square

После этих изменений компонент Square выглядит следующим образом:

Свойство onClick() в нативном DOM-компоненте указывает React установить слушатель событий щелчка.

Поскольку компоненты Square больше не поддерживают состояние, они получают значения от компонента Board и информируют компонент Board при клике по ним. В терминах React-компоненты Square теперь являются контролируемыми компонентами. Board их полностью контролирует.

Почему важна неизменяемость

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

Изменение данных с помощью мутации

Изменение данных без мутации

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

Сложные функции становятся простыми

Отслеживание изменений

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

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

Определение момента, когда необходима перерисовка в React

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

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

Компоненты-функции

Теперь мы изменим Square на компонент-функцию.

Заменим класс Square такой функцией:

Мы изменили this.props на props в обоих местах, где он встречается.

По очереди

Теперь нам нужно исправить очевидный дефект в нашей игре в крестики-нолики: буквы «O» не могут быть отмечены на доске.

Мы установим первый ход в «X» по умолчанию. Мы можем установить это значение по умолчанию, изменив начальное состояние в нашем конструкторе Board :

После применения этих изменений у вас должен получиться такой компонент Board:

Объявление победителя

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

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

Добавление путешествия во времени

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

Хранение истории ходов

Однако мы использовали slice() для создания новой копии массива squares после каждого перемещения и рассматривали его как неизменяемый. Теперь это позволит нам сохранять каждую прошлую версию массива squares и перемещаться между ходами, которые уже произошли.

Очередное поднятие состояния

Во-первых, мы установим начальное состояние для компонента Game в его конструкторе:

Удалить конструктор в Board.

Компонент Board теперь выглядит так:

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

Показ предыдущих ходов

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

Ранее мы узнали, что элементы React являются первоклассными объектами JavaScript; мы можем передавать их в наших приложениях. Чтобы отрисовывать несколько элементов в React, мы можем использовать массив React элементов.

Давайте сопоставим историю в методе render компонента Game :

Each child in an array or iterator should have a unique “key” prop. Check the render method of “Game”.

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

Выбор ключа

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

Представьте себе переход от

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

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

Ключи не должны быть глобально уникальными; они должны быть уникальными только между компонентами и их соседями. То есть уникальными только в пределах данного списка. В другом, к примеру соседнем списке, значения ключей могут совпадать со значениями текущего списка, но это никак не влияет на его работу, так как эти два подмножества ключей рассматриваются React полностью независимо, то есть они друг о друге не знают.

Реализация путешествия во времени

Сначала добавим stepNumber: 0 в начальное состояние в конструкторе Game :

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

Подведение итогов

Поздравляем! Вы создали игру в крестики-нолики, которая:

позволяет вам играть в крестики-нолики,

показывает, когда игрок выиграл,

хранит историю игры,

позволяет игрокам просматривать как историю игры, так и предыдущие версии игрового поля.

Отличная работа! Мы надеемся, что теперь вы почувствовали, что хорошо понимаете, как работает React.

Проверьте окончательный результат здесь: Окончательный результат

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

Отображение местоположения для каждого хода в формате (столбец, строка) в списке истории ходов.

Выделите текущий выбранный элемент в списке ходов.

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

Когда кто-то выигрывает, выделите три квадрата, которые привели к победе.

Когда никто не выигрывает, выведите сообщение о ничье.

Источник

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

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