Урок 1. React JS Material UI. Настройка React JS


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

Скринкаст по React.js

React.js — одна из самых популярных библиотек для создания сложных Frontend-приложений.

Однако, успешная разработка на нём требует хорошего понимания концепций, на которых он построен.

В этом скринкасте мы:

  • Познакомимся с основными понятиями и внутренним устройством React.js.
  • Разберёмся с тем, как создавать компоненты на React.js.
  • Разберём ряд подводных камней, на которые часто наступают начинающие React-разработчики.

Одна из главных особенностей React.js — свобода действий, существует огромное количество подходов к построению приложений с его помощью (redux, mobx и другие).

Они не являются частью собственно React.js, а представляют собой архитектурные надстройки и также постоянно развиваются. Мы осваиваем их на Основном и Продвинутом онлайн-курсах по React.JS.

Автор этого скринкаста – Роман Якобчук, с небольшой помощью в плане организации материала от Ильи Кантора.

Вы также можете скачать все скринкасты в виде архива с видео-файлами.

Актуальное видео смотреть онлайн

Россия 24. Последние новости России и мира

Рада в бешенстве: Зеленский готов на диалог с Россией. Последние новости из Украины — Россия 24

Прямой эфир 112 Украина

Полное видео программы «Новости»

Полное видео программы «Новости»

MercyMe — Best News Ever (Official Lyric V >►

Видео «Новости-N»: Пожар в торговом центре Николаева

Abu Bakr al-Baghdadi ra >►

Видео «Новости-N»: В Николаеве автомобиль проехал по бульварной части проспекта

Чем НОВОЕ оружие России НАПУГАЛО Пентагон? | Новости | Армия | Видео

Видео Новости N: марафон в Николаеве 2020

Видео новости | Вечерний Квартал 08.03.2013

El Paso, Texas, Shooting: Witness V >►

Turkish News V >►

Actress Anushka Shetty Birthday Special V >►

Павел Устинов: последние новости. Пикеты. Звездный флешмоб. Павел Устинов – задержание, видео, суд

Срочное заявление МИД России «США перешли ЧЕРТУ на Украине! Пощады не ждите!»

US Navy confirms multiple UFO v >►

Daily Bihar today updated news of all districts v >►

Kavabanga Depo Kolibri — Нет новостей (Mood v >►

GLOBALISTS PANIC! Leaked ABC News V >►

Huey Lewis And The News — If This Is It (Official V >►

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

Для этого лучше всего иметь всегда в закладках любимый сайт, который станет для Вас лучшим другом и помощником. «А как же выбрать такой сайт, когда их так много?» — спросите Вы. Лучшим выбором для Вас будет именно imperiya.by

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

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

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

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

Огромный выбор. Здесь Вы найдете видео на любой вкус. Даже самому заядлому киноману всегда найдется, что посмотреть у нас. Для детей есть мультфильмы в хорошем качестве, познавательные программы о животных и природе. Мужчины найдут для себя интересными каналы о новостях, спорте, автомобилях, а также о науке и технике. А для наших любимых женщин мы подобрали канала о моде и стиле, о знаменитостях, ну и конечно музыкальные клипы. Устроив вечер в кругу семьи, или с друзьями Вы сможете подобрать веселую семейную комедию. Влюбленная пара понежиться за просмотром любовной мелодрамы. После рабочего дня расслабиться помогает захватывающий сериал или детектив. Фильмы в HD формате нового времени и прошлых лет представлены на абсолютно любой вкус и могут удовлетворить потребности любого зрителя.

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

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

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

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

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

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

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

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

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

Не отказывайте себе в удовольствии, начните смотреть уже прямо сейчас! Знакомьтесь с обновлениями, с новинками, выбирайте то, что хотели бы посмотреть позже. Порадуйте себя и близких интересными фильмами в хорошем качестве!

Material UI + React JS как запустить хоть один пример?

если бы было все так просто, я ни одного примера не нашел во всем интернете!
я вставил JS код и пытался вызвать
React.render(, document.getElementById(‘example’));
на элемент, но не работает как и следовало ожидать)
сообщения console
You are using the in-browser JSX transformer. Be sure to precompile your JSX for production — facebook.github.io/react/docs/tooling-integration.
Inline JSX script:2 Uncaught SyntaxError: Unexpected identifier

let React = require(‘react’); // первая же строка дает ошибку

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вы можете увидеть, что именно мы будем разрабатывать здесь: Окончательный результат. Если код для вас непонятен, или если вы не знакомы с синтаксисом, не беспокойтесь! Цель учебника — помочь вам понять React и его синтаксис.

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

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

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

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

Если вам нужно повторить JavaScript, можно использовать данное руководство (хотя лично я предпочитаю это руководство). Обратите внимание, что в данном учебнике мы используем некоторые функции ES6 — недавней версии JavaScript: функции-стрелки, классы, операторы let и const. Вы можете использовать Babel REPL, чтобы проверить, во что компилируется код ES6.

Установка

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

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

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

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

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

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

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

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

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

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

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

Не удаляйте всю папку src , только файлы c кодом внутри нее. На следующем шаге мы заменим эти файлы примерами, необходимыми для нашего проекта.

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

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

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

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

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

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

Если вы застряли, посетите ресурсы сообщества поддержки. В частности, Reactiflux Chat — отличный способ быстро получить помощь. Если же вы не получили ответа или зашли в тупик, пожалуйста, сообщите нам в Git о проблеме, и мы вам поможем.

Обзор

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

Что такое React?

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

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

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

Здесь ShoppingList — это класс компонента React или тип компонента React. Компонент принимает параметры, называемые props (сокращение от properties — свойства), и возвращает иерархию представлений, отображаемых с помощью метода render .

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

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

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

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

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

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

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

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

Компонент Square отображает одиночную кнопку , а Board отображает 9 квадратов. Компонент Game отображает Board со значениями чисел-заполнителей, которые мы изменим позже. В настоящее время интерактивные компоненты отсутствуют.

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

Для эксперимента, давайте попробуем передать некоторые данные из нашего компонента Board в компонент Square .

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

Измените метод render компонента Square , чтобы он отображал это значение, поменяв на :

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

Поздравляем! Вы только что «передали свойство» из родительского компонента Board в дочерний компонент Square . Передача свойств — это то, как информация передается от родителей к потомкам в приложениях React.

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

Давайте заполнять компонент Square значением « X », когда мы щелкаем по нему. Сначала измените тег кнопки, который возвращается из функции render() компонента Square , следующим образом:

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

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

Обратите внимание, что с помощью onClick = <() =>alert (‘click’)> мы передаем функцию в качестве свойства onClick . Она срабатывает только после щелчка. Пропуск () => и запись onClick = — является распространенной ошибкой, которая генерирует предупреждение каждый раз, когда компонент перерисовывается.

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

Компоненты React могут иметь состояние, инициализируя this.state в своих конструкторах. Состояние this.state следует рассматривать как приватное для компонента React, в котором оно определено. Давайте сохраним текущее значение Square в this.state и изменим его при нажатии Square .

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

В классах JavaScript вам всегда нужно вызывать super при определении конструктора подкласса. Все классы компонентов React, имеющие конструктор, должны начинат его с вызова super(props) .

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

Замените this.props.value на this.state.value внутри тега .

Замените обработчик события () => alert() на () => this.setState() .

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

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

Вызывая this.setState из обработчика onClick в методе render компонента Square , мы говорим React повторно отрисовывать этот Square при каждом нажатии на его кнопку . После обновления свойство this.state.value компонента Square будет иметь значение « X », поэтому мы увидим X на игровом поле. Если вы нажмете на любой квадрат, в нём должен появиться X .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Можно предположить, что Board должен просто попросить у каждого Square значение его состояния. Хотя такой подход и возможен в React, мы его не одобряем, потому что код становится сложным для понимания, восприимчивым к ошибкам и трудным для рефакторинга. Вместо этого лучше всего хранить состояние игры в родительском компоненте Board , а не в каждом Square . Компонент Board может указать каждому Square , что отображать, передавая свойство, точно так же, как мы это делали, когда передавали число в каждый Square .

Топ-пост этого месяца:  Исследование эффективности нативного блокировщика Chrome

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

Поднятие состояния в родительский компонент является обычным явлением при рефакторинге компонентов React — давайте воспользуемся этой возможностью. Мы добавим конструктор в Board и установим его начальное состояние так, чтобы оно содержало массив с 9 нулями. Эти 9 нулей соответствуют 9 квадратам:

Когда мы позже заполним Board , игровая доска будет выглядеть примерно так:

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

В начале мы передали свойство value вниз по иерархии компоненту Square из Board , чтобы показывать числа от 0 до 8 в каждом Square . В другом предыдущем шаге мы заменили числа знаком « X », определяемым собственным состоянием Square. Вот почему Square в настоящее время игнорирует свойство value , переданное ему компонентом Board .

Теперь мы снова будем использовать механизм передачи свойств. Мы изменим Board , чтобы проинструктировать каждый отдельный Square о его текущем значении (« X », « O » или null ). У нас уже определен массив squares в конструкторе Board . Давайте изменим метод renderSquare в Board , чтобы читать значения из массива:

Каждый Square теперь получит свойство value , которое будет либо « X »/« O », либо null для пустых квадратов.

Далее нам нужно изменить то, что происходит при нажатии на квадрат. Компонент Board теперь знает, какие квадраты заполнены. Нам нужно создать для Square способ обновить состояние Board . Поскольку состояние считается приватным по отношению к компоненту, который его определяет, мы не можем обновлять состояние Board напрямую из Square .

Чтобы сохранить состояние Board приватным, мы передадим функцию из компонента Board компоненту Square . Эта функция будет вызываться при нажатии на квадрат. Мы изменим метод renderSquare в Board на:

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

Теперь мы передаем потомкам два свойства из Board в Square : value и onClick . Свойство onClick — это функция, которую Square может вызывать при нажатии. Внесем следующие изменения в Square :

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

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

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

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

При нажатии на квадрат вызывается функция onClick() , предоставляемая Board . Вот как это достигается:

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

При нажатии на кнопку React вызывает обработчик события onClick() , определенный в методе render() компонента Square .

Этот обработчик событий вызывает this.props.onClick() . Свойство onClick компонента Square было определено компонентом Board .

Так как Board передал onClick = <() =>this.handleClick(i)> в Square , Square при нажатии вызывает this.handleClick(i) .

Мы пока не определили метод handleClick() , поэтому наш код выдает крэш.

Атрибут onClick DOM-элемента имеет особое значение для React, поскольку он является нативным компонентом. Для пользовательских компонентов, таких как Square , наименование зависит от вас. Мы могли бы как угодно назвать метод onClick компонента Square или метод handleClick компонента Board . Однако в React принято использовать имена on[Event] для свойств, которые представляют события, и handle[Event] для методов, которые обрабатывают события.

Когда мы попытаемся кликнуть по квадрату, мы должны получить ошибку, потому что мы еще не определили handleClick . Теперь мы добавим handleClick в класс Board:

После этих изменений мы снова можем нажимать на квадраты, чтобы заполнить их. Однако теперь состояние хранится в компоненте Board вместо отдельных компонентов Square . При изменении состояния Board компоненты Square автоматически перерисовываются. Хранение состояния всех квадратов в компоненте Board в будущем позволит определить победителя.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Когда мы выразили Square как компонент-функцию, мы также изменили onClick= <() =>this.props.onClick()> на более короткий onClick= (обратите внимание на отсутствие скобок с обеих сторон). В классе мы использовали стрелочную функцию для доступа к правильному значению this , но в компоненте функции нам не нужно об этом беспокоиться.

По очереди

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

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

Каждый раз, когда игрок делает ход, xIsNext (логическое значение) будет инвертирован, чтобы определить, какой игрок пойдет дальше, и состояние игры будет сохранено. Мы обновим функцию handleClick в Board , чтобы инвертировать значение xIsNext :

С этим изменением «Х» и «О» могут сменяться. Давайте также изменим текст переменной status в методе render компонента Board , чтобы он отображал, какой игрок должен ходить следующим:

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

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

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

Мы будем вызывать calculateWinner(squares) в методе render компонента Board , чтобы проверить, выиграл ли игрок. Если игрок выиграл, мы можем отобразить текст, такой как «Победитель: X» или «Победитель: O». Заменим объявление переменной status в методе render компонента Board следующим кодом:

Теперь мы можем изменить функцию handleClick в Board , чтобы выполнять return раньше, игнорируя клик, если кто-то выиграл игру или Square уже заполнен:

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

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

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

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

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

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

Мы будем хранить прошлые массивы squares в другом массиве, называемом history . Массив history представляет все состояния Board , от первого до последнего хода, и имеет следующую форму:

Теперь нам нужно решить, какой компонент должен владеть состоянием history .

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

Мы хотим, чтобы компонент Game верхнего уровня отображал список прошлых ходов. Для этого ему понадобится доступ к history , поэтому мы поместим состояние history в компонент Game верхнего уровня.

Помещение состояния history в компонент Game позволяет нам удалить состояние squares из его дочернего компонента Board . Подобно тому, как мы «подняли состояние» из компонента Square в компонент Board , теперь мы поднимаем его из Board в компонент Game верхнего уровня. Это дает компоненту Game полный контроль над данными Board и позволяет ему инструктировать Board отрисовывать предыдущие ходы из history .

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

Далее у нас будет компонент Board , получающий свойства squares и onClick из компонента Game . Так как теперь у нас есть единый обработчик кликов в Board для всех Square , нам нужно будет передавать местоположение каждого Square в обработчик onClick , чтобы указать, на какой квадрат кликнули. Вот необходимые шаги для преобразования компонента Board :

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

Заменить this.state.squares[i] на this.props.squares[i] в методе renderSquare компонента Board .

Заменить this.handleClick(i) на this.props.onClick(i) в методе renderSquare компонента Board .

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

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

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

Наконец, нам нужно переместить метод handleClick из компонента Board в компонент Game . Нам также нужно изменить handleClick , поскольку состояние компонента Game структурировано по-другому. В методе handleClick компонента Game мы объединяем новые записи истории в history .

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

На данный момент компонент Board нуждается только в методах renderSquare и render . Состояние игры и метод handleClick должны находиться в компоненте Game .

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

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

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

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

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

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

Для каждого хода в истории игры в крестики-нолики мы создаем элемент списка
, который содержит кнопку . Эта кнопка имеет обработчик onClick , который вызывает метод this.jumpTo() . Мы еще не реализовали метод jumpTo() . Пока что мы должны увидеть список ходов, которые произошли в игре, и предупреждение в консоли инструментов разработчика, которое гласит:

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

Каждый дочерний элемент в массиве или итераторе должен иметь уникальное свойство » key «. Проверьте метод render компонента Game .

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

Выбор ключа

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

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

В дополнение к обновленным счетчикам, человек, читающий это, вероятно, сказал бы, что мы поменяли местами Петю и Васю и вставили между ними Лёню. Однако React — это компьютерная программа, которая не знает наших намерений. Поскольку это так, нам необходимо указать свойство key для каждого элемента списка, чтобы отличать его соседних элементов в этом списке. Один из вариантов — использовать строки vasia , petia , lyonia . Если бы мы отображали данные из базы данных, в качестве ключей могли бы использоваться идентификаторы (поле id) базы данных для Васи, Пети и Лёни.

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

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

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

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

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

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

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

В методе render компонента Game мы можем добавить ключ как
, и предупреждение React о ключах должно исчезнуть:

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

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

Далее мы определим метод jumpTo в Game , чтобы обновлять stepNumber . Мы также устанавливаем xIsNext в true , если число, на которое мы меняем stepNumber , является четным:

Теперь мы внесем несколько изменений в метод handleClick комопнента Game , который срабатывает при нажатии на квадрат.

Добавленное нами состояние stepNumber отражает текущий ход, отображаемый для пользователя. После того, как мы сделаем новый шаг, нам нужно обновить stepNumber , добавив stepNumber: history.length в качестве аргумента this.setState . Это гарантирует, что мы не застрянем, показывая тот же самый ход после того, как был сделан новый.

Мы также заменим чтение this.state.history на this.state.history.slice(0, this.state.stepNumber + 1) . Это гарантирует, что если мы «вернемся назад во времени», а затем сделаем новый шаг с этой точки, мы затрем всю «будущую» историю, которая теперь стала бы неверной.

Наконец, мы изменим метод render компонента Game , на данный момент всегда отрисовывающий последний ход, чтобы он отрисовывал текущий выбранный ход в соответствии со stepNumber :

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Tutorial: Intro to React

This tutorial doesn’t assume any existing React knowledge.

Before We Start the Tutorial

We will build a small game during this tutorial. You might be tempted to skip it because you’re not building games — but give it a chance. The techniques you’ll learn in the tutorial are fundamental to building any React app, and mastering it will give you a deep understanding of React.

This tutorial is designed for people who prefer to learn by doing. If you prefer learning concepts from the ground up, check out our step-by-step guide. You might find this tutorial and the guide complementary to each other.

The tutorial is divided into several sections:

  • Setup for the Tutorial will give you a starting point to follow the tutorial.
  • Overview will teach you the fundamentals of React: components, props, and state.
  • Completing the Game will teach you the most common techniques in React development.
  • Adding Time Travel will give you a deeper insight into the unique strengths of React.

You don’t have to complete all of the sections at once to get the value out of this tutorial. Try to get as far as you can — even if it’s one or two sections.

What Are We Building?

In this tutorial, we’ll show how to build an interactive tic-tac-toe game with React.

You can see what we’ll be building here: Final Result. If the code doesn’t make sense to you, or if you are unfamiliar with the code’s syntax, don’t worry! The goal of this tutorial is to help you understand React and its syntax.

We recommend that you check out the tic-tac-toe game before continuing with the tutorial. One of the features that you’ll notice is that there is a numbered list to the right of the game’s board. This list gives you a history of all of the moves that have occurred in the game, and is updated as the game progresses.

You can close the tic-tac-toe game once you’re familiar with it. We’ll be starting from a simpler template in this tutorial. Our next step is to set you up so that you can start building the game.

We’ll assume that you have some familiarity with HTML and JavaScript, but you should be able to follow along even if you’re coming from a different programming language. We’ll also assume that you’re familiar with programming concepts like functions, objects, arrays, and to a lesser extent, classes.

Топ-пост этого месяца:  Отзывчивая навигация по вкладкам (табам)

If you need to review JavaScript, we recommend reading this gu >let , and const statements. You can use the Babel REPL to check what ES6 code compiles to.

Setup for the Tutorial

There are two ways to complete this tutorial: you can either write the code in your browser, or you can set up a local development environment on your computer.

Setup Option 1: Write Code in the Browser

This is the quickest way to get started!

First, open this Starter Code in a new tab. The new tab should display an empty tic-tac-toe game board and React code. We will be editing the React code in this tutorial.

You can now skip the second setup option, and go to the Overview section to get an overview of React.

Setup Option 2: Local Development Environment

This is completely optional and not required for this tutorial!

Optional: Instructions for following along locally using your preferred text editor

This setup requires more work but allows you to complete the tutorial using an editor of your choice. Here are the steps to follow:

  1. Make sure you have a recent version of Node.js installed.
  2. Follow the installation instructions for Create React App to make a new project.
  1. Delete all files in the src/ folder of the new project

Don’t delete the entire src folder, just the original source files inside it. We’ll replace the default source files with examples for this project in the next step.

Add a file named index.css in the src/ folder with this CSS code.

Add a file named index.js in the src/ folder with this JS code.

Add these three lines to the top of index.js in the src/ folder:

Now if you run npm start in the project folder and open http://localhost:3000 in the browser, you should see an empty tic-tac-toe field.

We recommend following these instructions to configure syntax highlighting for your editor.

If you get stuck, check out the community support resources. In particular, Reactiflux Chat is a great way to get help quickly. If you don’t receive an answer, or if you remain stuck, please file an issue, and we’ll help you out.

Now that you’re set up, let’s get an overview of React!

React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”.

React has a few different kinds of components, but we’ll start with React.Component subclasses:

We’ll get to the funny XML-like tags soon. We use components to tell React what we want to see on the screen. When our data changes, React will efficiently update and re-render our components.

Here, ShoppingList is a React component >props (short for “properties”), and returns a hierarchy of views to display via the render method.

The render method returns a description of what you want to see on the screen. React takes the description and displays the result. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write. The

If you’re curious, createElement() is described in more detail in the API reference, but we won’t be using it in this tutorial. Instead, we will keep using JSX.

JSX comes with the full power of JavaScript. You can put any JavaScript expressions within braces inside JSX. Each React element is a JavaScript object that you can store in a variable or pass around in your program.

The ShoppingList component above only renders built-in DOM components like

Inspecting the Starter Code

If you’re going to work on the tutorial in your browser, open this code in a new tab: Starter Code. If you’re going to work on the tutorial locally, instead open src/index.js in your project folder (you have already touched this file during the setup).

This Starter Code is the base of what we’re building. We’ve provided the CSS styling so that you only need to focus on learning React and programming the tic-tac-toe game.

By inspecting the code, you’ll notice that we have three React components:

The Square component renders a single and the Board renders 9 squares. The Game component renders a board with placeholder values which we’ll modify later. There are currently no interactive components.

Passing Data Through Props

To get our feet wet, let’s try passing some data from our Board component to our Square component.

We strongly recommend typing code by hand as you’re working through the tutorial and not using copy/paste. This will help you develop muscle memory and a stronger understanding.

In Board’s renderSquare method, change the code to pass a prop called value to the Square:

Change Square’s render method to show that value by replacing with :

After: You should see a number in each square in the rendered output.

Congratulations! You’ve just “passed a prop” from a parent Board component to a child Square component. Passing props is how information flows in React apps, from parents to children.

Making an Interactive Component

Let’s fill the Square component with an “X” when we click it. First, change the button tag that is returned from the Square component’s render() function to this:

If you click on a Square now, you should see an alert in your browser.

To save typing and avo >this , we will use the arrow function syntax for event handlers here and further below:

Notice how with onClick= <() =>alert(‘click’)> , we’re passing a function as the onClick prop. React will only call this function after a click. Forgetting () => and writing onClick= is a common mistake, and would fire the alert every time the component re-renders.

As a next step, we want the Square component to “remember” that it got clicked, and fill it with an “X” mark. To “remember” things, components use state.

React components can have state by setting this.state in their constructors. this.state should be cons >this.state , and change it when the Square is clicked.

First, we’ll add a constructor to the class to initialize the state:

Now we’ll change the Square’s render method to display the current state’s value when clicked:

  • Replace this.props.value with this.state.value ins > tag.
  • Replace the onClick= <. >event handler with onClick= <() =>this.setState()> .
  • Put the className and onClick props on separate lines for better readability.

After these changes, the tag that is returned by the Square’s render method looks like this:

By calling this.setState from an onClick handler in the Square’s render method, we tell React to re-render that Square whenever its is clicked. After the update, the Square’s this.state.value will be ‘X’ , so we’ll see the X on the game board. If you click on any Square, an X should show up.

When you call setState in a component, React automatically updates the child components inside of it too.

The React Devtools extension for Chrome and Firefox lets you inspect a React component tree with your browser’s developer tools.

The React DevTools let you check the props and the state of your React components.

After installing React DevTools, you can right-click on any element on the page, click “Inspect” to open the developer tools, and the React tabs (“⚛️ Components” and “⚛️ Profiler”) will appear as the last tabs to the right. Use “⚛️ Components” to inspect the component tree.

However, note there are a few extra steps to get it working with CodePen:

  1. Log in or register and confirm your email (required to prevent spam).
  2. Click the “Fork” button.
  3. Click “Change View” and then choose “Debug mode”.
  4. In the new tab that opens, the devtools should now have a React tab.

Completing the Game

We now have the basic building blocks for our tic-tac-toe game. To have a complete game, we now need to alternate placing “X”s and “O”s on the board, and we need a way to determine a winner.

Lifting State Up

Currently, each Square component maintains the game’s state. To check for a winner, we’ll maintain the value of each of the 9 squares in one location.

We may think that Board should just ask each Square for the Square’s state. Although this approach is possible in React, we discourage it because the code becomes difficult to understand, susceptible to bugs, and hard to refactor. Instead, the best approach is to store the game’s state in the parent Board component instead of in each Square. The Board component can tell each Square what to display by passing a prop, just like we did when we passed a number to each Square.

To collect data from multiple children, or to have two child components communicate with each other, you need to declare the shared state in their parent component instead. The parent component can pass the state back down to the children by using props; this keeps the child components in sync with each other and with the parent component.

Lifting state into a parent component is common when React components are refactored — let’s take this opportunity to try it out.

Add a constructor to the Board and set the Board’s initial state to contain an array of 9 nulls corresponding to the 9 squares:

When we fill the board in later, the this.state.squares array will look something like this:

The Board’s renderSquare method currently looks like this:

In the beginning, we passed the value prop down from the Board to show numbers from 0 to 8 in every Square. In a different previous step, we replaced the numbers with an “X” mark determined by Square’s own state. This is why Square currently ignores the value prop passed to it by the Board.

We will now use the prop passing mechanism again. We will modify the Board to instruct each indiv >’X’ , ‘O’ , or null ). We have already defined the squares array in the Board’s constructor, and we will modify the Board’s renderSquare method to read from it:

Each Square will now receive a value prop that will either be ‘X’ , ‘O’ , or null for empty squares.

Next, we need to change what happens when a Square is clicked. The Board component now maintains which squares are filled. We need to create a way for the Square to update the Board’s state. Since state is considered to be private to a component that defines it, we cannot update the Board’s state directly from Square.

Instead, we’ll pass down a function from the Board to the Square, and we’ll have Square call that function when a square is clicked. We’ll change the renderSquare method in Board to:

We split the returned element into multiple lines for readability, and added parentheses so that JavaScript doesn’t insert a semicolon after return and break our code.

Now we’re passing down two props from Board to Square: value and onClick . The onClick prop is a function that Square can call when clicked. We’ll make the following changes to Square:

  • Replace this.state.value with this.props.value in Square’s render method
  • Replace this.setState() with this.props.onClick() in Square’s render method
  • Delete the constructor from Square because Square no longer keeps track of the game’s state

After these changes, the Square component looks like this:

When a Square is clicked, the onClick function provided by the Board is called. Here’s a review of how this is achieved:

  1. The onClick prop on the built-in DOM component tells React to set up a click event listener.
  2. When the button is clicked, React will call the onClick event handler that is defined in Square’s render() method.
  3. This event handler calls this.props.onClick() . The Square’s onClick prop was specified by the Board.
  4. Since the Board passed onClick= <() =>this.handleClick(i)> to Square, the Square calls this.handleClick(i) when clicked.
  5. We have not defined the handleClick() method yet, so our code crashes. If you click a square now, you should see a red error screen saying something like “this.handleClick is not a function”.

The DOM element’s onClick attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. We could give any name to the Square’s onClick prop or Board’s handleClick method, and the code would work the same. In React, it’s conventional to use on[Event] names for props which represent events and handle[Event] for the methods which handle the events.

When we try to click a Square, we should get an error because we haven’t defined handleClick yet. We’ll now add handleClick to the Board class:

After these changes, we’re again able to click on the Squares to fill them, the same as we had before. However, now the state is stored in the Board component instead of the individual Square components. When the Board’s state changes, the Square components re-render automatically. Keeping the state of all squares in the Board component will allow it to determine the winner in the future.

Since the Square components no longer maintain state, the Square components receive values from the Board component and inform the Board component when they’re clicked. In React terms, the Square components are now controlled components. The Board has full control over them.

Note how in handleClick , we call .slice() to create a copy of the squares array to modify instead of modifying the existing array. We will explain why we create a copy of the squares array in the next section.

Why Immutability Is Important

In the previous code example, we suggested that you use the .slice() method to create a copy of the squares array to modify instead of modifying the existing array. We’ll now discuss immutability and why immutability is important to learn.

There are generally two approaches to changing data. The first approach is to mutate the data by directly changing the data’s values. The second approach is to replace the data with a new copy which has the desired changes.

Data Change with Mutation

Data Change without Mutation

The end result is the same but by not mutating (or changing the underlying data) directly, we gain several benefits described below.

Complex Features Become Simple

Immutability makes complex features much easier to implement. Later in this tutorial, we will implement a “time travel” feature that allows us to review the tic-tac-toe game’s history and “jump back” to previous moves. This functionality isn’t specific to games — an ability to undo and redo certain actions is a common requirement in applications. Avoiding direct data mutation lets us keep previous versions of the game’s history intact, and reuse them later.

Detecting changes in mutable objects is difficult because they are modified directly. This detection requires the mutable object to be compared to previous copies of itself and the entire object tree to be traversed.

Detecting changes in immutable objects is considerably easier. If the immutable object that is being referenced is different than the previous one, then the object has changed.

Determining When to Re-Render in React

The main benefit of immutability is that it helps you build pure components in React. Immutable data can easily determine if changes have been made which helps to determine when a component requires re-rendering.

You can learn more about shouldComponentUpdate() and how you can build pure components by reading Optimizing Performance.

We’ll now change the Square to be a function component.

In React, function components are a simpler way to write components that only contain a render method and don’t have their own state. Instead of defining a >React.Component , we can write a function that takes props as input and returns what should be rendered. Function components are less tedious to write than classes, and many components can be expressed this way.

Replace the Square class with this function:

We have changed this.props to props both times it appears.

When we modified the Square to be a function component, we also changed onClick= <() =>this.props.onClick()> to a shorter onClick= (note the lack of parentheses on both sides).

We now need to fix an obvious defect in our tic-tac-toe game: the “O”s cannot be marked on the board.

We’ll set the first move to be “X” by default. We can set this default by modifying the initial state in our Board constructor:

Each time a player moves, xIsNext (a boolean) will be flipped to determine which player goes next and the game’s state will be saved. We’ll update the Board’s handleClick function to flip the value of xIsNext :

With this change, “X”s and “O”s can take turns. Try it!

Let’s also change the “status” text in Board’s render so that it displays which player has the next turn:

After applying these changes, you should have this Board component:

Declaring a Winner

Now that we show which player’s turn is next, we should also show when the game is won and there are no more turns to make. Copy this helper function and paste it at the end of the file:

Given an array of 9 squares, this function will check for a winner and return ‘X’ , ‘O’ , or null as appropriate.

We will call calculateWinner(squares) in the Board’s render function to check if a player has won. If a player has won, we can display text such as “Winner: X” or “Winner: O”. We’ll replace the status declaration in Board’s render function with this code:

We can now change the Board’s handleClick function to return early by ignoring a click if someone has won the game or if a Square is already filled:

Congratulations! You now have a working tic-tac-toe game. And you’ve just learned the basics of React too. So you’re probably the real winner here.

Adding Time Travel

As a final exercise, let’s make it possible to “go back in time” to the previous moves in the game.

Storing a History of Moves

If we mutated the squares array, implementing time travel would be very difficult.

However, we used slice() to create a new copy of the squares array after every move, and treated it as immutable. This will allow us to store every past version of the squares array, and navigate between the turns that have already happened.

We’ll store the past squares arrays in another array called history . The history array represents all board states, from the first to the last move, and has a shape like this:

Now we need to dec >history state.

Lifting State Up, Again

We’ll want the top-level Game component to display a list of past moves. It will need access to the history to do that, so we will place the history state in the top-level Game component.

Placing the history state into the Game component lets us remove the squares state from its child Board component. Just like we “lifted state up” from the Square component into the Board component, we are now lifting it up from the Board into the top-level Game component. This gives the Game component full control over the Board’s data, and lets it instruct the Board to render previous turns from the history .

First, we’ll set up the initial state for the Game component within its constructor:

Next, we’ll have the Board component receive squares and onClick props from the Game component. Since we now have a single click handler in Board for many Squares, we’ll need to pass the location of each Square into the onClick handler to indicate which Square was clicked. Here are the required steps to transform the Board component:

  • Delete the constructor in Board.
  • Replace this.state.squares[i] with this.props.squares[i] in Board’s renderSquare .
  • Replace this.handleClick(i) with this.props.onClick(i) in Board’s renderSquare .

The Board component now looks like this:

We’ll update the Game component’s render function to use the most recent history entry to determine and display the game’s status:

Since the Game component is now rendering the game’s status, we can remove the corresponding code from the Board’s render method. After refactoring, the Board’s render function looks like this:

Finally, we need to move the handleClick method from the Board component to the Game component. We also need to modify handleClick because the Game component’s state is structured differently. Within the Game’s handleClick method, we concatenate new history entries onto history .

Unlike the array push() method you might be more familiar with, the concat() method doesn’t mutate the original array, so we prefer it.

At this point, the Board component only needs the renderSquare and render methods. The game’s state and the handleClick method should be in the Game component.

Showing the Past Moves

Since we are recording the tic-tac-toe game’s history, we can now display it to the player as a list of past moves.

We learned earlier that React elements are first-class JavaScript objects; we can pass them around in our applications. To render multiple items in React, we can use an array of React elements.

In JavaScript, arrays have a map() method that is commonly used for mapping data to other data, for example:

Using the map method, we can map our history of moves to React elements representing buttons on the screen, and display a list of buttons to “jump” to past moves.

Let’s map over the history in the Game’s render method:

For each move in the tic-tac-toes’s game’s history, we create a list item
which contains a button . The button has a onClick handler which calls a method called this.jumpTo() . We haven’t implemented the jumpTo() method yet. For now, we should see a list of the moves that have occurred in the game and a warning in the developer tools console that says:

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

Let’s discuss what the above warning means.

When we render a list, React stores some information about each rendered list item. When we update a list, React needs to determine what has changed. We could have added, removed, re-arranged, or updated the list’s items.

Imagine transitioning from

In addition to the updated counts, a human reading this would probably say that we swapped Alexa and Ben’s ordering and inserted Claudia between Alexa and Ben. However, React is a computer program and does not know what we intended. Because React cannot know our intentions, we need to specify a key property for each list item to differentiate each list item from its siblings. One option would be to use the strings alexa , ben , claudia . If we were displaying data from a database, Alexa, Ben, and Claudia’s database IDs could be used as keys.

When a list is re-rendered, React takes each list item’s key and searches the previous list’s items for a matching key. If the current list has a key that didn’t exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved. Keys tell React about the identity of each component which allows React to maintain state between re-renders. If a component’s key changes, the component will be destroyed and re-created with a new state.

key is a special and reserved property in React (along with ref , a more advanced feature). When an element is created, React extracts the key property and stores the key directly on the returned element. Even though key may look like it belongs in props , key cannot be referenced using this.props.key . React automatically uses key to dec >key .

It’s strongly recommended that you assign proper keys whenever you build dynamic lists. If you don’t have an appropriate key, you may want to consider restructuring your data so that you do.

If no key is specified, React will present a warning and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list’s items or inserting/removing list items. Explicitly passing key= silences the warning but has the same problems as array indices and is not recommended in most cases.

Keys do not need to be globally unique; they only need to be unique between components and their siblings.

Implementing Time Travel

In the tic-tac-toe game’s history, each past move has a unique ID associated with it: it’s the sequential number of the move. The moves are never re-ordered, deleted, or inserted in the middle, so it’s safe to use the move index as a key.

In the Game component’s render method, we can add the key as
and React’s warning about keys should disappear:

Clicking any of the list item’s buttons throws an error because the jumpTo method is undefined. Before we implement jumpTo , we’ll add stepNumber to the Game component’s state to indicate which step we’re currently viewing.

First, add stepNumber: 0 to the initial state in Game’s constructor :

Next, we’ll define the jumpTo method in Game to update that stepNumber . We also set xIsNext to true if the number that we’re changing stepNumber to is even:

We will now make a few changes to the Game’s handleClick method which fires when you click on a square.

The stepNumber state we’ve added reflects the move displayed to the user now. After we make a new move, we need to update stepNumber by adding stepNumber: history.length as part of the this.setState argument. This ensures we don’t get stuck showing the same move after a new one has been made.

We will also replace reading this.state.history with this.state.history.slice(0, this.state.stepNumber + 1) . This ensures that if we “go back in time” and then make a new move from that point, we throw away all the “future” history that would now become incorrect.

Finally, we will modify the Game component’s render method from always rendering the last move to rendering the currently selected move according to stepNumber :

If we click on any step in the game’s history, the tic-tac-toe board should immediately update to show what the board looked like after that step occurred.

Congratulations! You’ve created a tic-tac-toe game that:

  • Lets you play tic-tac-toe,
  • Indicates when a player has won the game,
  • Stores a game’s history as a game progresses,
  • Allows players to review a game’s history and see previous versions of a game’s board.

Nice work! We hope you now feel like you have a decent grasp on how React works.

Check out the final result here: Final Result.

If you have extra time or want to practice your new React skills, here are some ideas for improvements that you could make to the tic-tac-toe game which are listed in order of increasing difficulty:

  1. Display the location for each move in the format (col, row) in the move history list.
  2. Bold the currently selected item in the move list.
  3. Rewrite Board to use two loops to make the squares instead of hardcoding them.
  4. Add a toggle button that lets you sort the moves in either ascending or descending order.
  5. When someone wins, highlight the three squares that caused the win.
  6. When no one wins, display a message about the result being a draw.

%d1%83%d1%80%d0%be%d0%ba 1 react js material ui %d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0 react js

Comment : %d1%83%d1%80%d0%be%d0%ba 1 react js material ui %d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0 react js

2020 © OnlineMakeMoney.work — Author Tuong Nguyen

All videos under the management of youtube OnlineMakeMoney.work is not responsible for content.

Page rendered in 0.2796 seconds.

Урок 1. React JS Material UI. Настройка React JS

Показать панель управления

  • Опубликовано: четверг, 10 августа 2020 г.
  • Все уроки курса по React JS Material UI тут:
    https://webformyself.com/category/premium/javascript-premium/reactjspremium/

    С этого урока мы начнем настраивать рабочее окружение для того, чтобы работать с библиотекой material-ui.

    Из урока вы узнаете, как максимально быстро и эффективно развернуть рабочее окружение для React JS. Данный урок – это настройка React JS.

    Комментарии

    Серж Пятигорцев Алутьев

    Здравствуйте Владилен! Подскажите пожалуйста, ведь данный полноценный курс по React JS имеется в линейке продуктов Михаила Русакова с Вашим авторством? То есть если нужна качественная образовательная программа по React JS обратиться к Михаилу Русакову? Правильно Вас понял?

    Урок 1. React JS Material UI. Настройка React JS

    Показать панель управления

    • Опубликовано: 10 авг 2020
    • Все уроки курса по React JS Material UI тут:
      webformyself.com/category/premium/javascript-premium/reactjspremium/
      С этого урока мы начнем настраивать рабочее окружение для того, чтобы работать с библиотекой material-ui.

    Из урока вы узнаете, как максимально быстро и эффективно развернуть рабочее окружение для React JS. Данный урок — это настройка React JS.
    Урок 1. React JS Material UI. Настройка React JS — thexvid.com/video/VOKtCal_PXk/видео.html

    Комментарии • 3

    Здравствуйте Владилен! Подскажите пожалуйста, ведь данный полноценный курс по React JS имеется в линейке продуктов Михаила Русакова с Вашим авторством? То есть если нужна качественная образовательная программа по React JS обратиться к Михаилу Русакову? Правильно Вас понял?

    Урок 1. React JS Material UI. Настройка React JS

    Все уроки курса по React JS Material UI тут:
    webformyself.com/category/premium/javascript-premium/reactjspremium/
    С этого урока мы начнем настраивать рабочее окружение для того, чтобы работать с библиотекой material-ui.

    Из урока вы узнаете, как максимально быстро и эффективно развернуть рабочее окружение для React JS. Данный урок — это настройка React JS.
    Урок 1. React JS Material UI. Настройка React JS — ch-me.org/videos/video-VOKtCal_PXk.html

    Komentáře

    Серж Пятигорцев Алутьев

    Здравствуйте Владилен! Подскажите пожалуйста, ведь данный полноценный курс по React JS имеется в линейке продуктов Михаила Русакова с Вашим авторством? То есть если нужна качественная образовательная программа по React JS обратиться к Михаилу Русакову? Правильно Вас понял?

    Полное руководство по React JS material-ui

    26.06.2020 Комментарии к записи Полное руководство по React JS material-ui отключены 613 Просмотров

    От автора: в React JS material-ui — это часть Material Design. Material Design — это язык дизайна, впервые представленный Google в 2014 году. Это визуальный язык, который использует макеты на основе сетки, гибкую анимацию и переходы, дополнения и эффекты глубины, такие как освещение и тени. Цель Material Design сводится к трем вещам: Создание, Унификация и Настройка.

    Создание — Material Design направлен на предоставление визуального языка, который синтезирует классические принципы дизайна. Унификация — он нацелен на разработку единой базовой системы, которая объединяет пользовательский интерфейс на разных платформах, устройствах и методах ввода. И Настройка обеспечивает визуальный язык и гибкую основу для инноваций и брендинга.

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

    Приступаем к работе

    material-ui — это набор компонентов React, который реализует Google Material Design (material-ui недавно выпустили v1 библиотеки). Эти компоненты работают изолированно, это означает, что они являются само-поддерживающими и вводят только те стили, которые они должны отображать.

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

    Далее, давайте рассмотрим некоторые из основ material-ui, относящихся к Material Design, и посмотрим, как она настраивается.

    Типографика

    Когда речь заходит о Material Design, шрифтом по умолчанию является Roboto. Однако material-ui не поставляется с Roboto по умолчанию. Шрифт можно импортировать в проект React с использованием одного из двух методов. Из CDN:

    Установить с помощью NPM

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

    Затем вы можете импортировать его в свой проект следующим образом:

    material-ui также предоставляет компонент под названием Typography. Компонент Typography в основном позволяет отображать текст в приложении.

    Свойство variant помогает применять стили оформления темы, а color — это цвет компонента. Он поддерживает цвета тем, которые подходят для компонента.

    CSS Baseline

    Если вы писали код front-end, вы уже должны знать о normalize.css. Если нет, это набор для нормализации элементов HTML и атрибутов стилей. material-ui предоставляет собственную версию normalize.css — CssBaseline, компонент, который обеспечивает изящный, последовательный и простой набор базовых стилей. CSSBaseline делает следующее:

    Закрепляет отступы во всех браузерах

    Применяет цвет фона Material Design по умолчанию.

    Включает сглаживание шрифтов для лучшего отображения шрифта Roboto

    Базовый размер шрифта не указывается в html, но предполагается, что это 16px (размер браузера по умолчанию)

    Сетка

    Адаптивный пользовательский интерфейс Material Design основан на макете с 12 столбцами. Эта сетка создает визуальную согласованность между макетами.

    Система сетки material-ui характеризуется следующим:

    Содержит два типа макетов: контейнеры и элементы

    Ширина элементов задается в процентах, поэтому они всегда являются гибкими и их размер указан относительно их родительского элемента

    Элементы имеют отступы для создания интервала между отдельными элементами.

    Существует пять контрольных точек сетки: xs, sm, md, lg и xl

    Иконки

    Иконки — важная часть Material Design, они используются в кнопках для обозначения действия, для передачи информации и т.д. Они используются для обозначения команды, файла, устройства или каталога.

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

    Иконки в material-ui могут отображаться с использованием двух методов: Icon для отображения шрифтов иконок и SvgIcon для визуализации SVG контуров.

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

    Material- ui также содержит пакет, который поставляется с предустановленными иконками, которые будут использоваться в приложении React. Это совсем другой пакет, и он включает официальные иконки Material, преобразованные в компоненты SvgIcon. Вы можете установить его с помощью следующей команды:

    Кнопки

    Кнопки позволяют пользователям выполнять действия и делать выбор одним нажатием. Они помогают сообщать о действии, которое может предпринять пользователь. Поскольку компоненты material-ui изолированы, вам нужно импортировать компонент Button.

    Компонент Button может принимать множество реквизитов, таких как цвет, вариант, размер и т.д. Полный список вы можете посмотреть здесь.

    Кнопки в Material-ui и Material Design в целом могут принимать любую из следующих форм:

    Плоские кнопки

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

    Контурные кнопки

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

    Поднятые кнопки

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

    Гибкие кнопки действия

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

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

    Компоненты material-ui

    material-ui содержит много компонентов пользовательского интерфейса, которые помогают создавать приложение React в теме Material Design. Давайте рассмотрим некоторые компоненты material-ui. Для каждого из компонентов приведен пример, и вы можете просмотреть код на CodeSandbox, перейдя по соответствующим ссылкам.

    Панель приложения

    Панель приложения, ранее известная как панель действий в Android, выполняет роль меню навигации. Это панель инструментов, используемая для брендинга, навигации, поиска и действий. Чтобы использовать панель приложения, необходимы эти два компонента из material-ui:

    Навигация

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

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

    Вкладки

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

    Списки

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

    Карточки

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

    Модальные компоненты

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

    Управляет стеком диалога

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

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

    Отключает прокрутку содержимого страницы при открытии

    Автоматически добавляет соответствующие роли ARIA

    Список сетки

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

    Дополнительный пример списка Grid можно увидеть ниже, он использует GridListTileBar для добавления наложения в каждый GridListTile. Наложение может содержать заголовки, подзаголовки и вторичное действие — в этом примере IconButton — которые могут использоваться для передачи дополнительной информации.

    Таблицы

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

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

    Заключение

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

    В то же время, если вы пытаетесь провести ребрендинг, Material Design может и не быть тем, что вы ищете. Вы хотите, чтобы ваш бренд выглядел как сотни других веб-сайтов в Интернете? Вы также можете изучить другие библиотеки Material Design, такие как response-md, materialize (CSS framework).

    Автор: Yomi

    Редакция: Команда webformyself.

    Топ-пост этого месяца:  Взаимодействие Vue js TypeScript преимущества и примеры разработки проектов
  • Добавить комментарий