Почему Create React App плохо подходит для новичков основные недостатки


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

React: Установка и настройка

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

Почему React?

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

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

Установка и настройка

Есть несколько способов начать работу с React. Во-первых, мы взглянем на CodeSandbox и CodePen. Если вы хотите сразу начать играть с кодом, это хороший способ!

Затем мы сосредоточимся на установке проекта React с помощью Create React App — которое дает вам отличную отправную точку для ваших проектов без необходимости тратить время на настройку среды сборки.

React в CodeSandbox

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

Перейдите на https://codesandbox.io/s и нажмите «React».

Мгновенно вы окажетесь в среде React, которая была настроена с помощью create-react-app. Мы рассмотрим этот метод далее в статье! Если вы хотите начать программирование без настройки локальной установки, это отличный способ! Такие задачи, как сборка, преобразование и управление зависимостями, все автоматизированы, и вы можете легко поделиться ссылкой на все, над чем вы работали!

React в CodePen

Альтернативой CodeSandBox является CodePen . Многие разработчики используют CodePen для демонстрации своей работы, создавая «прототипы» для быстрых демонстраций кода или «проекты», когда задействовано несколько файлов. CodeSandbox, безусловно, более многофункциональный для работы с React, однако CodePen также является хорошим решением.

Создаем приложение React

Create React App — это инструмент (созданный разработчиками из Facebook), который даст вам огромное преимущество при создании приложений React. Он обрабатывает все настройки, поэтому вам не нужно знать ни Babel, ни Webpack. Вы просто запускаете первоначальную установку, и вы сразу же окажетесь в локальной среде разработки!

Установка с помощью Create React App

Все, что нам нужно сделать, это открыть наш терминал и запустить следующую команду:

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

Запустите указанную выше команду, чтобы начать установку! Дайте ему любое имя, которое вам нравится..

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

Успех! Теперь вы можете открыть папку вашего проекта и проверить созданную файловую структуру.

Несколько команд были добавлены в файл package.json :

  • npm start запускает сервер разработки, включая автоматическую перезагрузку страницы при внесении изменений
  • npm run build связывает приложение в статические файлы для производства в папку build
  • npm test запускает тестов с помощью Jest
  • npm run eject выводит настройки вашего приложения из create-react-app, которые позволяет вам настроить конфигурацию вашего проекта

Запуск вашего приложения

Теперь давайте запустим наш локальный сервер! Из папки вашего приложения запустите:

Ваше приложение запустится в браузере на localhost:3000

Каждый раз, когда вы начинаете новый проект с помощью create-react-app, вы будете иметь последнюю версию React, React-DOM и React-Scripts. Теперь давайте кратко рассмотрим некоторые функции create-react-app.

Возможности Create-React-App

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

Прод сборка

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

Сама команда build преобразует ваш код React в код, который понимает браузер (используя Babel). Он также оптимизирует ваши файлы для лучшей производительности, объединяя все ваши файлы JavaScript в один файл, который будет минимизирован для сокращения времени загрузки.

Тестирование вашего приложения

В комплекте с create-react-app поставляется JEST, который позволяет проверить ваш код с помощью команды npm test . Он будет запускаться аналогично npm start , он будет перезапускать ваши тесты каждый раз, когда вы вносите изменения.

Для тех, кто заинтересован в тестировании компонентов с помощью Jest, все, что вам нужно, это либо добавить суффиксы к нужным файлам, .spec.js либо .test.js , либо переместить файлы с тестами в папку __tests__ . Jest запустит ваши тесты для указанных вами файлов.

Ejecting

Всякий раз, когда вы создаете приложение с помощью create-react-app, ваши параметры сборки не могут быть изменены, так как они были предварительно настроены в react-scripts. Тем не менее, запустив npm run eject , вы можете получить полный контроль над конфигурацией вашего приложения.

Конфиг будет скопирован в каталог вашего приложения в папку config , а скрипты — в папку scripts . Затем вы можете отредактировать настройки Webpack, Babel и ESLint в соответствии с вашими пожеланиями.

Сообщения об ошибках

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

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

Заключение

Мы видели, как начать играть с React в CodeSandbox и CodePen. И мы рассмотрели, как настроить локальную среду разработки с помощью create-react-app. Вам не нужно тратить время на установку зависимостей или настройку процесса сборки — вы можете сразу перейти к написанию кода!

Недостатки React

Здравствуйте. Расскажите пожалуйста о недостатках, архитектурный просчетах, неудобствах и т.д. с которыми вы сталкивались при написании приложений с использованием React.

В рунете (да и не только) при поиске какой-либо информации об этой библиотеке я (и надеюсь не только я) постоянно натыкаюсь на восторженные статьи и комментарии, пестрящие фразами «react замечателен», «react прекрасен» и т.д. При этом какая-либо аргументированная критика отсутствует. Может создаться впечатление что он действительно «прекрасен», но мы же понимаем, что ничего идеального не существует.

В общем небольшая пятиминутка ненависти

Добавлено через 20 часов 37 минут
Что-то совсем тихо. Придется начинать самому.

Компонентный поход — позволяет повторно использовать уже написанный код.

Фигушки! В большинстве случаев повторное использование это не использование кода как есть, а использование уже имеющегося кода (читай компонента) с небольшими изменениями/дополнениями. А вот с этим у реакта всё очень и очень печально. Например:

Нам нужен DatePicker. Берем готовый или старательно пишем свою реализацию. Предположим, что он нас полностью устраивает и мы стали использовать его во всех проектах как вдруг появляется заказчик который заявляет: «Ваш DatePicker — унылое Г ибо в нем отсутствует кнопка «вперед на неделю»».

И всё. Приплыли. React не позволяет нам, оставив изначальную реализацию не тронутой, написать отдельную расширенную версию с хотелкой заказчика, максимально используя уже написанное. Так?

Почему Create React App плохо подходит для новичков: основные недостатки

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

Честное предупреждение

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

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

Если вы из тех, кто желает сразу же окунуться в Реакт и полностью изучить его, включая сборку и необходимый инструментарий — это потрясающе! Начните с этого. А ещё я бы посоветовала этот великолепный курс от «Frontend Masters»: «Современные веб-приложения»

Разрушители легенд: спецвыпуск о практичности в Реакте

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

Миф #1: для Реакта необходимо использовать встроенные стили.

Неа! Отнюдь. Можно использовать CSS, как и обычно. Потратив уйму времени на рефакторинг гигантского объёма CSS-кода, я поняла, насколько это важно. Реакт относительно новый и ему пока не приходилось выдерживать испытание переделками дизайнов. Если бы мне пришлось заново продираться через тысячи строк встроенных стилей ради обновления padding и line-height , меня бы, как разработчика, это наверняка расстроило.

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

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

Миф #2: для атрибутов элемента придётся использовать JavaScript-синтаксис, который совсем не похож на HTML.

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

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

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

Миф #3: чтобы опробовать Реакт, нужно понимание всех инструментов для сборки.

И действительно, для Реакта нужно использовать инструменты для сборки, поэтому, как правило, туториалы начинаются с этого. Но я бы посоветовала начинать с того, что если вы совсем новичок, вам следовало бы поковыряться на CodePen, JSBin или JSFiddle. Это — хороший способ повторять и усваивать уроки, прежде чем вкладывать кучу сил в совершенно новую технологию. С целью сделать первый шаг, в сегодняшних примерах я планирую использовать CodePen.

Использование Реакта в типичных приложениях

В типичных приложениях на React 0.14+ прежде всего нам потребуется React и ReactDOM:

А затем вызов ReactDOM.render :

Использование Реакта в CodePen

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

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

Также, чтобы приступить к работе, потребуется отладчик для Реакта в виде расширения для Chrome или для Firefox, которые отлично подходят для отладки виртуальной DOM.

В случае CodePen можете выбрать «Отладочный режим», и это расширение автоматически определит Реакт:

Использование Реакта

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

Разберём это по частям. В последней строке мы находим id главного div ( main ) и отображаем в нём компонент , загружающий всё приложение Реакта. Чтобы увидеть созданный DOM-элемент, можно воспользоваться вкладкой «Реакт» в отладчике.

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

И последнее, что стоит отметить, это то, что вместо класса для элемента мы используем className . Это подвох, если вы привыкли писать HTML-разметку для веб-страниц. К счастью, это легко исправить. В этой документации отлично описан JSX и его синтаксис.

Следующим шагом будет расширение приложения с помощью компонента. Название для заголовка можно выбирать на свой вкус, но для наглядности, пусть оно отражает его роль в документе. Можно заметить, что если нам также понадобиться добавить элемент навигации, сделать это не составит труда. Вот такая же страница со стандартным бутстраповским рядом кнопок для компонента , и более семантичным h1 для нашего «Привет, мир!» вместо div :

Ничего сложного, правда? Всё равно, что строительные блоки любой веб-страницы. Мы создали навигацию с шапкой, и применили эти компоненты к компоненту приложения, который отображён в body. Единственным подвохом последнего примера может показаться непонятный дополнительный div вокруг и . Это потому, что мы должны всегда возвращать один элемент. У нас не может быть два сестринских элемента, вот и приходится оборачивать их в один div.

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

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

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

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

И снова возьмём первое демо (давайте использовать его на протяжении всей статьи):

У компонента статьи в блоге весьма простая разметка, так что начнём с этого:

Добавим произвольную переменную и обработчик события и посмотрим, как это работает. Первое, что стоит учесть — если мы используем JSX, то фигурные скобки сообщат Реакту, что мы готовы использовать JavaScript. Так что наша переменная будет выглядеть как .

Мы хотим добавить оператор переменной внутрь вызова функции render, но прежде, чем вернуть разметку. Можно затем получить к ней доступ, вызвав переменную, в данном случае . Событие по клику — встроенный обработчик onClick , вероятно, противоречащий хорошему тону, к которому вы привыкли. Это имя мы выбрали сами, когда как render — метод фреймворка. Мы вызваем и пишем метод, хранимый как tryClick (произвольное имя) внутри того же компонента, к примеру:

Синтаксис для событий в Реакте начинается с «on» и использует верблюжийРегистр. Например:

  • click = onClick
  • mouseEnter = onMouseEnter
  • keyPress = onKeyPress

Здесь можно найти полный список всех поддерживаемых событий.

Объединение Реакта с другими библиотеками (в данном случае Greensock)

Для анимации я предпочитаю GSAP. В Реакте можно использовать и другие библиотеки, поэтому объеденим GSAP с Реактом и посмотрим, что будет.

Мы хотим обращаться к другим библиотекам в нужный момент, поэтому нужно убедиться, что они вызываются сразу же после первого метода render. И в этом нам поможет метод componentDidMount . Ещё немного о других методах жизненного цикла мы поговорим позже, но пока для нас важно то, что этот метод вызывается сразу же после вставки компонента в документ.

Если вы привыкли к jQuery, то наверняка знакомы с выборкой элементов прямо из DOM. В этом случае, даже при анимировании DOM-элементов мы воспользуемся методом getDOMNode() Реакта, а не просто выберем их. А также вы заметите, что на самом деле мы вызываем функцию для анимации в компоненте приложения, и просто передаем её ниже нашим боксам. (Чтобы увидеть анимацию, возможно придётся нажать кнопку «Rerun»)

Возможно, вы привыкли обращаться к DOM через jQuery или ванильный JavaScript. Можно по-прежнему делать так, но здесь мы обращаемся к частям DOM через getDOMNode() и refs , в этой строке: var sq1 = this.refs.squares1.getDOMNode(); . Немного подробнее об этом написано в документациии Реакта.

У Реакта есть и другие способы добавить динамики вашим проектам — React-Motion Ченга Лу просто замечателен, еще стоит отметить React-GSAP-Enhancer.

Создание глобальной функции-хелпера

Можно даже писать функции-хелперы, к которым легко может обращаться множество компонентов. Для этих функций подходит та же точечная нотация, что и для this.functionName . Мы сохраняем функцию-хелпер (в этом примере на CodePen — прямо в начале файла, но в реальных приложениях это был бы отдельный файл) и объявляем каждую из них в качестве объекта, таким же способом, как и в структуре компонента.

Что-то вроде правильно отформатированной даты в первом демо со статьями блока могло бы выглядеть так:

И использовано вот так:

Настоящее дело: управление состоянием

Хорошо! Теперь, когда мы разобрались со строительными блоками, перейдём к одной из самых класссных вещей.

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

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

  1. Первое — это состояние. Оно — принадлежность компонента, а значит, его область видимости ограничена компонентом, и мы будем обращаться к нему так: . Можно обновить состояние, вызвав this.setState() .
  2. Второе касается того, как передавать (предназначенные только для чтение) данные от родителя к компоненту (вроде того, как приложение было родителем для header в первом примере). Мы зовём это props, как в слове «property» (свойство), и будем использовать его прямо в компоненте посредством . Дочерние элементы компонента не могут менять эти данные.

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

Прелесть виртуальной DOM в том, что Реакт ищет только те ноды в DOM, которые нужно обновить.

Теперь я прочитала кучу всего про состояние, но думаю, Весу удалось выразиться яснее всех, поэтому я перефразирую его: Если вы привыкли к jQuery, то все данные у вас хранятся в DOM. Реакту это ни к чему, он хранит данные в объекте (состоянии), а затем отрисовывает вещи, в зависимости от объекта. Это как главный эталон, от которого всё зависит.

Props на практике

Для начала давайте просто опробуем this.props , добавив к компоненту Header , а после обратимся к нему в приложении.

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

Практика

Давайте немного разовьем это и поработаем с состояниями. Если мы в итоге собираемся менять this.state , нужно довести его до готовности. Для этого воспользуемся getInitialState , что позволит установить, какое состояние самое первое. Без этого мы не сможем добавить состояние.

Давайте просто менять фон в зависимости от выбора пользователя.

Важная часть этого, которую нужно учитывать — требуется функция handleChange

С нативными select-ами в обычном DOM ничего подобного бы не понадобилось, поскольку они автоматически обновлялись бы по выбору пользователей. В Реакте все состояния управляются компонентом, поэтому если нужно, чтобы input или select следил за изменениями, вам придется описать это в коде. Это означает, что за состояние отвечает компонент, а не пользователь.

На первый взгляд неясно, ради чего было столько возиться, но мы намеренно оставляем эти примеры маленькими. По-настоящему Реакт проявляет себя, когда дело доходит до больших сложностей. Как бы я ни любила jQuery (а я до сих пор люблю jQuery, это не то, что можно выразить булевой переменной true/false), вам не удастся уйти от довольно частой проверки при изменениях. В Реакте это решается тем, что эта необходимость устраняется благодаря простоте направления потока данных, по этой же причине его проще отслеживать в очень сложных приложениях.

Основные понятия состояния

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

Реакт показывает лучшие результаты работы, когда мы обновляем состояния и перерисовываем низкоуровневые компоненты. По сути мы хотим, чтобы эти компоненты оставались без состояния и брали данные из высокоуровневых компонентов. Компоненты на верхних уровнях иерархии (вроде нашего приложения) работают отлично именно тогда, когда запоминают состояния. Таким образом они управляют большей частью логики взаимодействия и передают состояние вниз с помощью props. Тем не менее, моменты, при которых у каждого компонента будет собственное состояние, не исключены. Однако, важно помнить, что соседние компоненты должны «общаться» не напрямую, а через родительский компонент.

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

Из такой идеологии разработки напрямую следует то, почему я также не советую использования props в getInitialState , и здесь можно подробнее почитать о том, почему это считается антипаттерном.

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

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

Информацию об элементе можно также получить с помощью так называемого ref. Использование Ref-ов осуществляется за счёт прикрепления их к любому компоненту. Затем они возвращаются во время вызова метода render() и после мы можем ссылаться на них снаружи render() . Это крайне полезно.

И снова возьмём первый пример на CodePen. Давайте на минутку задумаемся, как создаются эти новые статьи в блоге, и при этом применим ref-ы.

На каждом поле формы у нас есть ref, наподобие такого:

А на самом элементе формы мы вызываем:

который ссылается на функцию createPost выше функции render, и использует ref-ы для хранения информации из отправляемой формы:

а затем можно обратиться к нему в состоянии приложения с помощью this.props :

Это крайне удобно, поскольку теперь есть переменная post , с объектом, хранящим своё название (показано тут), дату, детали и т.д. Мы по-прежнему не храним ничего из этого в состоянии приложения, а только лишь дали приложению возможность это использовать. Рассмотрим это подробнее в следующем разделе, заодно с keys.

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

Keys и использование Ref-ов

В последнем разделе мы создали способ хранить данные, собранные в форме, без передачи их куда-либо. Это потому, что в Реакте мы стремимся управлять этим состоянием в верхнем уровне иерархии. Для сохранения этого состояния, мы запускаем начальное состояние с пустым объектом. Вот где в итоге сохраняются данные из формы.

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

У каждого дочернего элемента в массиве должен быть уникальный key.prop . Это важно, поскольку при любой возможности Реакт всё равно будет повторно использовать существующий DOM. Реакт использует keys для отслеживания того, какие элементы в DOM он должен обновить. Он избавляет нас от перерисовки всех DOM-элементов, когда это требуется. Это улучшает производительность нашего приложения.

Теперь давайте снова обратимся к приложению, и посмотрим, что мы делаем с только что сохранёнными данными из формы:

Можно видеть, что когда приложение отображается, мы используем Object.keys для создания нового массива. Затем берём .map() с функцией renderPost , которую создадим заранее. Для тех, кто не знаком с .map() , она полезна для создания массива из существующего массива, можете представить её в виде цикла.

Теперь давайте создадим эту самую функцию renderPost, которую только что вызвали. Мы передаём ключ в качестве параметра и назначаем его в качестве ключа, индекса, и создаём объект, который мы называем details, чтобы хранить информацию о состоянии статьи.

Может показаться странным, что мы передаём key и index , но внутри компонента невозможно обратиться к ключу prop , поэтому мы передаём ещё один ключ под названием index . Функция renderPost просто создаёт компонент для каждого элемента в массиве, с подробностями, переданными вниз по иерархии, к которым затем можно обратиться. Это довольно-таки круто, поскольку, если в нашем состоянии что-то обновится, это распространится вниз по иерархии и мы сможем управлять им в одном месте.

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

А теперь всё вместе

Теперь, когда с keys всё ясно, взглянем на минутку на общую картину. Мы рассмотрели getInitialState , componentDidMount и render , но в Реакте есть ещё один метод при подключении — componentWillMount . Он похож на componentDidMount , но выполняется прямо перед первым отображением компонента.

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

Заключение

О Реакте написано гораздо больше, а эта статья лишь начало. Надеюсь, это путешествие новичка позволило понять, как подготовиться к работе с Реакта. Эта статья растянулась аж на 20 страниц, но при этом мы даже не затронули массу других важных тем в связи с Реактом, включающих ES6, Browserify, Gulp, Webpack, несметное число альтернативных реализаций и многое другое.

Опять же, для дальнейшего изучения, я настоятельно рекомендую погрузиться в курс Веса Боса, и он предлагает 10%-скидку для читателей CSS-Tricks с кодом CSSTRICKS, а также посмотреть некоторые видео на Frontend Masters. У Майкла Джексона есть прекрасный учебный курс, на котором можно зарегистрироваться для участия (мы ждём его на Trulia в Сан-Франциско в марте!). Есть также отличный учебник Артемия Федосеева под названием «Основы Реакта» и этот список Артёма Сапегина, который стоит занести в закладки. Ну и не забывайте, что документация по Реакту тоже очень неплоха. Счастливого изучения!

Большое спасибо Майклу Джексону, Весу Босу и Вэл Хед за проверку этой статьи.

P.S. Это тоже может быть интересно:

Если вам понравилась статья, поделитесь ей!

Учебник: введение в 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 .

Чтобы собрать данные из нескольких дочерних элементов или обеспечить взаимодействие двумя дочерними компонентами, вам нужно объявить общее состояние в их родительском компоненте. Родительский компонент может передать состояние обратно дочерним компонентам, используя свойства 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 , чтобы использовать два цикла для создания квадратов вместо их жесткого кодирования.

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

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

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

Фронтэнд: как воткнуть Реакт в существующий сайт

Люди часто спрашивают «а как воткнуть Реакт в существующий сайт? У нас есть огромный фронтэнд на каком-нибудь Джквери или не дай бог Ангуларе первом, мы устали от всего этого, но огромный рефакторинг нам никто не даст (и слава богу — иначе это затянется на десятилетия), как нам начать втыкать Реакт потихоньку?»

Для этого нам нужно познакомиться с работой Реакта и узнать, почему существуют react-pdf, redocx (рендеринг в .docx ��) и даже react-tv, не говоря уж про react-native.

UPD : добавил более богатый пример (а не хеллоу ворлд небольшой) и блок “Как отправить в продакшен”. Заодно был обновлен скрипт билда, чтобы он работал только с Джсом, а не с нашей демкой на src/index.html . И демку на Гитхабе.

Реакт не рендерит

Реакт (библиотека react, весом в 2.2 Кб) не занимается рендером. Задача Реакта — построить дерево элементов и обновлять его когда обновляются стейт или пропы.

Рендерингом занимаются другие библиотеки: react-dom, react-native, redocx, react-tv и другие.

На примере react-dom это выглядит так: ReactDOM.render(React.createElement(App), document.getElementById(«app»)) , где App — ваше Реакт-приложение.

Какой практический смысл с этого? Вы можете заняться рефакторингом постепенно: не сразу переделывать всё приложение, а писать реакт-приложения и рендерить их через кучу ReactDOM.render() .

Про тулинг — Бейбель, Вебпак и другое

«Женя, но Реакт же сложный! Нужно много всего устанавливать, ставить, вебпак и бейбель чтобы всё работало!».

Ну, как мы видим в примере выше, нет — работает в браузере даже через тег

Обучение Create React App — 30-минутный курс

Ускоренный курс по Create React App

Чему вы научитесь?

  • Как создавать React приложения
  • Как разработать и настроить учётные записи пользователей
  • Научитесь использовать самые последние библиотеки и инструменты React

Содержание

Раздел 1: Создайте свой БЛОГ/ПРИЛОЖЕНИЕ в REACT за 30 минут

Описание

Если вы JavaScript разработчик, то вы скорее всего знаете насколько трудно бывает убедиться в том, что используемые вами инструменты быстры и надёжны. Каждый день выходят обновления и каждый раз приходится учиться чему-то новому. На сегодняшний день доступно просто огромное количество различных библиотек, поэтому найти лучшие из лучших не так-то просто. Но, вам не стоит волноваться — я здесь, чтобы помочь вам в этой нелёгкой ситуации. Вы же не просто так попали на наш курс по Create React App, правда? В нём я расскажу вам о самых полезных/важных секретах, которые скрывает самая лучшая библиотека JS на сегодня.

Почему вы должны записаться на этот курс по «Create React App»?

Так как я сам являюсь программистом — я могу вас понять. Бывает очень сложно найти надёжный курс, который предложит вам самую актуальную и полезную информацию о React JS. Если вы когда-либо планировали наконец начать изучение React JS, то скорее всего может понять о чём я говорю. Данный курс был создан как раз, чтобы избавиться от этой проблемы — он был создан в качестве источника информации по «Create React App», который вобрал в себя всё необходимое для любого разработчика.

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

Перспективы обучения

Итак, теперь у вас есть общее представление о том, почему вы должны выбрать наш курс. Но остался ещё один вопрос. Зачем мне вообще нужно проходить React JS уроки и курсы? Почему именно React из всего многообразия библиотек в JS так важен для изучения?

Этому есть несколько причин. Как я уже ранее упоминал, React, по мнению многих, является одной из лучших библиотек для JavaScript. Он был создан и поддерживается Facebook (и небольшой помощи некоторых сторонних разработчиков). Главная цель библиотеки не изменилась с момента своего создания и остаётся всё той же — предоставить JavaScript разработчикам быстрый и надёжный инструмент, который бы они смогли использовать для создания и улучшения своих сайтов и приложений без проблем и каких-либо преград. Однако большинство онлайн уроков по «Create React App» рассказывает только лишь о технической стороне React (создании приложений, учётных записей пользователей и т.д.), полностью забывая или игнорируя тот факт, насколько может быть важен этот инструмент для таких разработчиков как вы и я. В отличие от них, этот курс не только научит вас технической стороне вопроса создания блога или приложения, но и поможет составить вам полную картину возможностей и функций библиотеки React.

Для кого подойдёт данный курс?

Если вы JavaScript разработчик, который ищет способ улучшить свои навыки и расширить багаж знаний о лучших библиотеках для JS — то этот курс определённо подойдёт для вас! Не имеет значения являетесь ли вы профессионалом или новичком, вы совершенно точно найдёте для себя новые и полезные вещи по React JS.

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

Критика работы с React Native: наш опыт

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

В свете последних тенденций на рынке разработки ПО Android разработчик BytePace, Виктор Кинько, расскажет о некоторых подобных сложностях, с которыми ему пришлось столкнуться за последние несколько месяцев работы с React Native.

React Native адаптирует javascript под разработку для мобильных устройств. Это достигается тем, что для сборки проектов он использует несколько сборщиков — Metro Bundler, который интерпретирует JS-код и представляет ресурсы и сборщик целевой системы. В моем случае это был gradle для android. В теории приложение react-native должно запускаться довольно просто. Команда react-native run-android включает metro bundler и выполняет сборку приложения для всех подключенных android-устройств и эмуляторов.

В реальности оказалось, что даже на этом этапе есть сложности. На нашем проекте постоянно возникала ошибка «Unable to download JS bundle», которая означала, что bundler не может транслировать код в нативный. Как позже выяснилось, из-за того, что он не запустился. StackOverflow подтвердил догадки и подсказал, что стоит запускать bundler отдельным потоком с помощью команды react-native start. Это позволяет перезапускать bundler только если поменялся package.json, потому процедура не сильно замедляет разработку.

Package.json — это файл, содержащий набор внешних модулей для приложения. На npmjs.com находится большое количество различных библиотек для react-native, расширяющих функционал и упрощающих разработку. Многие библиотеки (например, firebase) используют нативные функции, а потому должны быть связаны напрямую с нативным кодом. Для этого используется команда react-native link , которая должна настраивать эти связи с нативным кодом.

Из-за того, что все библиотеки пишутся в разное время, они используют разные версии SDK и требуют разного подхода. Иногда бывает так, что библиотеки несовместимы друг с другом, или последняя версия библиотеки оказывается экспериментальной, и сами разработчики советуют понизить версию до предпоследней. Довольно часто link не настраивает все требуемые зависимости. Так, для вышеупомянутого firebase требуется добавить множество дополнительных библиотек в нативном коде, подключить различные внешние репозитории, модифицировать mainApplication.java (и это только для android!). Для firebase есть достаточно понятная инструкция по выполнению этих действий, но для других библиотек она присутствует не всегда.

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

• rmdir node_modules /s /q && npm cache clean-force && npm i

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

• rmdir android/app/build /s /q

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

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

Установить приложение на подключенное устройство или эмулятор. Большинство ошибок сборки случаются именно здесь, и часть из них понятна, но часть довольно иррациональна и «лечится» перезапуском всего процесса.

Представим процесс сборки последовательностью команд для одного проекта (уже имеющего realm, redux, react-navigation, ещё около десяти библиотек) после подключения firebase.

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

Кстати об отладке. Отладчик React Native имеет проблемы не только с запуском. Исправление ошибок, найденных вследствие теста, тоже довольно болезненный процесс. В react-native JS-код транслируется в Native-код, но в процессе трансляции обфусцируется. Так что если не хотите видеть ошибки типа «null pointer exception in zzz.yyy()», то нужно пользоваться встроенным отладчиком, не получится просто читать exception’ы в logcat. При ошибке отладчик показывает красный “экран смерти” с её описанием, более-менее подталкивающим в сторону пути исправления. Но и с этой частью есть проблемы.

Хорошо, когда ошибка выглядит так:

Здесь действительно понятно, что происходит — вместо ожидаемого объекта массива в переменной this.state.noteArray.map находится undefined, из-за чего возникает пресловутая TypeError. Исправить её можно переходом на app.js:14 и проверкой значения в данной переменной перед использованием.

Хуже, когда ошибка выглядит так:

Изображения взяты из интернета, но я видел их и «вживую». И несмотря на то, что они показываются в runtime, эта ошибка не связана с тем, что что-то было сделано неверно именно в вашем коде. Это может быть следствием того, что вы неверно установили библиотеку, или если в ваших импортах есть несовместимые зависимости, или что-то пошло не так в native-коде, а ошибку пытается отловить React. Каждая ошибка индивидуальна и решается крайне по-разному. Хорошо, что существует StackOverflow и хоть какой-то режим отладки.

Еще хуже, когда ошибка не воспроизводится в debug. С данной ситуацией я столкнулся при попытке собрать приложение с новой версией React с поддержкой x64-архитектур для Android. При установке приложения с дебаггером всё работает отлично. Но как только я делаю сборку тестеру на телефон, всё прекращает работать и ломается как только доходит до взаимодействия с базой данных. Чтобы отладить неотлаживаемое, на скорую руку используем консольные сообщения, в роли которых в данном случае выступал компонент react toastAndroid. Этот компонент выводит на экран короткий текст по достижению определенной строчки кода. Методично, желательно деля код пополам, локализуем функцию, в которой происходит ошибка, и выясняем, что метод Object.assign(<>, item) не работает в новой версии React. Повезло, что можно было заменить эту функцию на более короткую <. item>при сохранении функционала приложения, но поиск этой ошибки обошелся в примерно десяток часов работы.

После было проведено небольшое исследование в поисках причин. Как обнаружилось, для интерпретации JS-кода в debug и production версиях React Native использует разные Javascript-движки: для отладки Chrome JS engine, а в работе JavaScriptCore. Да, React Native не переводит JavaScript в нативный код, а интерпретирует по ходу выполнения. При этом отладочный движок работает куда стабильнее, а потому баги всё чаще прокрадываются в production. К примеру, в этой статье показано, как форматирование даты работает в разных условиях. Возвращаясь к ошибке: так вышло, что после обновления версии React Native веб-движок production-версии потерял поддержку Object.assign(). А отладочный движок остался тот же.

Пожалуй, худший вариант — это случай, когда приложение ломается в случайных местах, только в production-версии и без каких-либо логов со стороны React Native. Пример: после установки релизной версии приложения на телефон оно «работает какое-то время», а потом «выключается без ошибки или предупреждения в случайный момент». Причём ошибка воспроизводится не на всех устройствах. В конце концов, методом проб и ошибок (и обнаружением того, что вышеупомянутый Firebase Crashlytics не присылает соответствующих ошибок) удалось выловить логи падения, которые выглядели так:

Этот текст даже не относится к нашему приложению, он даже не был отмечен красным. Но после того, как я его получил и отправился на форумы, я обнаружил, что новая версия React Native сломана. И предыдущая была сломана. На официальном Issue Tracker ошибка «Android crashes: signal 11 (SIGSEGV)» существовала уже два месяца, и к моей удаче за два дня до того, как я обратился туда(!), было предложено экспериментальное решение, которое исправило ошибку.

Иронично, что некоторые разработчики, которым приходилось сталкиваться с Android Studio, были в недоумении по поводу того, что в IDE есть такие опции как build/clean project или file/invalidate caches. Это требуется для того, чтобы избавиться от аномального поведения gradle, от ложных сообщений об ошибках и предупреждениях, от ошибок синхронизации. Разработчики спрашивали: «почему мы должны делать работу за нашу IDE, в таких ситуациях эти команды должны выполняться автоматически». И их можно понять, но в то же время современные IDE и так делают всю сложную работу за кадром. А эти разработчики попросту не работали с React Native.

Всё рассказанное — это единичные случаи, случившиеся за последние несколько недель. Здесь я не описываю сложности запуска приложений с Expo, с настройкой стиля кода в babel/eslint, не ругаю Javascript за излишнюю гибкость, не рассказываю как на одном из проектов почти полностью пропала возможность отладки из-за связки redux/realm. Учитывая описанные сложности поддержки и разработки и тот факт, что для двух систем это всё умножается на два, стоит задуматься, действительно ли React Native выгоден для разработки? После того как мы завершили наш третий проект на этом языке, мы решили, что нет. Как вы считаете?

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

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

Меня на реакт подбил знакомый, работающий с React JS. До этого работал на на нативе android , iOs.
Достаточно легко было нарисовать простой список элементов, получаемых с сервера. Но когда дело пошло дальше: новостная лента, вебвью, перехват и обработка запросов, работа с БД — началась адская боль и страдания. Наверное надо быть js ником в третьем поколении, чтобы это выдержать. Война с версиями библиотек. Под айос еще как-то. pod install и все. Но с андроидом с градлом. Не в градле дело, а в вечных конфликтах версий. Да, запустилось на андроиде и не идет на айос. И наоборот. Куча кастомных приблуд. Куча ограничений. Не советую никому, кто будет писать что-то функциональное, мало-мальски сложнее презентационной странички. Тем более если вы отлично дружите с нативной разработкой на типизированных языках. После реакта пропало желание смотреть в сторону Flutter и прочих кросплатформенных приблуд. Пока что углубляюсь в котлин и свифт.

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

А даёт ли это какой-то результат в скорости разработки или качестве.

Как написавший 3 аппы в 2012-2014 годах, на более качественной с точки зрения перфоманса(хороший мультитрединг), кроссплатформе Adobe AIR, я ушел все равно в чистый нейтив. Сегодня просто божественные инструменты для того, чтобы силами одного разраба сделать Swift и Kotlin нейтив: кодогенерации в оба языка, схожие UI-либы, даже местами можно копипастить код как есть. Ни один сегодня опытный разраб не вляпается в кроссплатформу.
Правда есть одна работающая бизнес-модель кроссплатформы, это Unity для игр, но там надо много платить — только на таких финпотоках можно поддерживать кроссплатформенный движок в актуальном состоянии

Вы знаете, я в итоге пришел к тому, что для MVP лучше использовать не RN, а RN + webview. Я не представляю, как делать на RN сложные графические вещи, анимации и пр. Исходя из этого делаю предположение, что RN — это больше про аналог мобильных версий сайтов завёрнутых в приложение. Так вот вёрстку и бизнес логику можно заменить вебвью, а от RN использовать только нужное: пуши, геолокацию и другие специфические штуки. И вот этот подход очень сильно ускоряет разработку,т.к. в итоге нужно соблюсти только кроссбраузерность(safari + chrome).

PS
По факту разрабатывали одно приложение на RN, потом переделали на RN + webview. По качеству стало лучше — перестало крашиться, анимации стали быстрее. По скорости разработки несравнимый буст. И релизишся быстро и разрабатываешь намного быстрее.

PSS
Надеюсь webview не запретят.

Может быть вам больше подойдёт Cordova? Мы на Cordova даже виртуальную реальность реализовали.

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

Интересно было почитать о вашем опыте. Часто чешутся руки его изучить, особенно после комментариев под моей очередной статьей об Ionic Framework, что React Native круче.

Расскажите как сложно верстать кастомный дизайн приложения в React Native? Само собой в сравнении с нативом.

Здравствуйте, спасибо за отзыв!
С Ionic совсем не знаком, потому не знаю насколько React лучше или хуже, но опыт несомненно интересный.

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

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

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

В своё время мы тоже прошли этот путь, от Cordova до наивной разработки. В начале у всех разработчиков, пришедших из веба, есть боязнь использования каких‐то Kotlin и Swift, но все не так страшно на практике, и даже затягивает )) Многие англоязычные блогеры замечают, React Native хорош . для создания прототипа. Большие проекты очень тяжело поддерживать в RN. Далее будут всплывать проблемы с переходом от старой версии RN к более новой.

Ещё хочется добавить. Жирный минус в RN, по крайней мере для iOS, отсутствие поддержки контроллеров. Мы работали с дополненной реальностью, и был готовый контроллер из ARKit. Модуль для RN в этом случае поступает просто, создаёт статический класс ARView, который живёт всегда. Приходится как-то останавливать его. короче, убийца Айфона (его батарейки )))

RN вроде и не предназначен для подобного рода приложений( игры/дополненная реальность )
Для них логичней какой-нибудь Unity или Unreal попробовать

Довольно.. забавное описание.
Ощущение, что процесс разработки происходил на линукс с его вечным цирком в плане прав доступа.
Бандлер обычно запускают отдельной командой, т.к это удобней( и можно почистить его кеш в случае странностей, т.е npm start — —rest-cache )
Часть ошибок( из показанного на скринах ) — ошибки связанные именно с JS. К примеру, вместо массива прилетел с бука объект или вообще null. Как ни странно, метода map у него не будет и попытка выполнения его вызовет ошибку.
Еще часть — когда отладка происходит на подключенном к ПК телефоне( обычно помогает adb reverse )
Далее, по крашам. Если приложение просто вылетает( тихо выключается ) — это сбой в нативной части. Если вместо приложения — вдруг красный(отладка) / белый(релиз) экран — сбой в JS части.

Package.json — файл, относящийся к npm, т.е пакетному менеджеру.
Штука позволяет довольно удобно настраивать версии пакетов.
npm — это не чисто RN-приблуда. Соотв., на npmjs полным-полно модулей, к RN не относящихся( там и для React.JS модули есть и для Node.JS и для многого другого )

Да, подключение модулей( особенно, файербейса и ФБ/Твиттера/Гугла — это обычно самая боль ) не всегда происходит запросто. Однако в разработке, подключение модулей происходит нечасто. Это не то действие, которое выполняется ежедневно и по 10 раз в день. Если вы подключили файербейс к андроиду, второй раз это делать не придется.
Если это сколь-нибудь большое приложение, то подавляющая часть времени — это работа с версткой( и эта часть реально сильно сокращается в сравнении с независимой разработкой для 2 платформ ).

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

Основани часть ошибок, связанных при установке-подключении модулей, возникает из-за непонимания очевидных вещей:
Если был подключен нативный модуль( т.е был выполнен react-native link ), очевидно, что проект нужно полностью пересобрать. Желательно, почистить от старой сборки. Особенно проблемами с этим грешит android и gradle( этот «гений» создает столько мусора, что сам порой в нем разобраться не может ).
Если был подключен просто_JS модуль( т.е просто установлен через пакетный менеджер, без линковки ), полная переборка не требуется достаточно перезагрузить приложение( всм, Reload JS ).
В обоих вариантах лучше перезапустить бандлер( прибить и выполнить npm start — —reset-cache ).

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

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

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

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

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

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

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

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

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

Почему запуск index.html не будет работать для сборки «create-react-app»?

Я новичок в create-react-app . Я хочу знать, почему открытие формы index.html сборки не работает? Я знаю, что для выполнения сборки сборки serve -s build должна использоваться serve -s build , но я хочу знать, почему приложение для создания сборки не запускается без обслуживания.

Я объясню далее: что я делаю.

  1. create-react-app helloworld
  2. Внесите некоторые изменения кода и убедитесь, что приложение работает нормально.
  3. npm run build или yarn run build . Теперь у меня будет мой каталог ./build созданный с помощью index.html .
  4. Теперь я просто открываю index.html в браузере, и это не сработает.

Я хочу понять, почему это не работает? Почему я должен служить сборке, чтобы он работал?

Следующий ответ был дан на похожую тему одним парнем из Reddit

Проект был построен при условии, что он размещен в корне сервера.

Create React App — способ сделать приложение раздутым

26.03.2020 Комментарии к записи Create React App — способ сделать приложение раздутым отключены 137 Просмотров

От автора: когда Create React App впервые был запущен в июле 2020 года, для новичков он считался лучшим способом начать работу с React. В те дни новичкам предлагалось создать приложение React с Webpack с нуля или загружать один из множества шаблонов. Появление Create React App стало глотком свежего воздуха.

Годы спустя мы застопорились в прогрессе, так как мы стремимся делать вещи проще и проще в использовании. Наше бесконечное желание оптимизировать и добавлять функции сделало Create React App неудобным в использовании и пугающим для большинства новичков (и некоторых опытных пользователей).

Раздутая файловая структура

Извлечение в Create React App всегда было чрезвычайно неприятным опытом. Если вы когда-нибудь решались запустить npm run eject, вы, вероятно, знакомы с потоком конфигураций и многочисленных файлов, которые могут казаться невероятно пугающими для новичков. Но давайте предположим, что мы никогда не извлекаем, вот что вы получаете из коробки:

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

Сразу же вас встретят две отдельные папки: public и src. В папке public вы видите favicon.ico и manifest.json помимо index.html. В папке src у вас есть два CSS-файла, четыре Javascript-файла и добавленный logo.svg просто для удовольствия.

К этому моменту вы уже можете представить, что думает большинство новичков: «Я думал, что это поможет мне изучить React и быстро начать создавать компоненты?»

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

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

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

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

Перспектива новичка

Давайте подумаем об этом с точки зрения новичка. И давайте предположим, что у нас откуда-то было понимание того, что нужно игнорировать папку public и сосредоточиться на src. Возможно, с этой точки зрения мы можем начать понимать, почему Create React App не всегда может быть лучшим вариантом по умолчанию.

CSS-файлы

Во-первых, вас встречают два CSS-файла, и ваш первый вопрос может звучать так: «Куда делись мои стили?».

Через несколько секунд вы можете подумать, что index.css — это куда вы помещаете глобальные стили, а App.css — куда вы помещаете специфичные для компонента стили. Тем не менее, это не совсем так, так как App.css не является автоматически областью компонентов. Если вы включите его, стили будут применяться ко всему приложению.

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

Файлы Javascript

Вероятно, мы можем выяснить, что index.js является точкой входа нашего приложения, а App.js является компонентом верхнего уровня. Эта не сложно, но что с этими двумя другими файлами?

App.test.js, конечно, кажется предназначенным для тестирования, но подождите, я еще даже не выучил React! React поставляется с тестовой средой? Она используем Jest или Mocha? Мне всегда нужно тестировать, чтобы использовать React?

Ох, и это еще не все. Что это за serviceWorker.js? Быстрый поиск в Google по «service worker» говорит мне, что это как-то связано с автономными функциями и прогрессивными веб-приложениями.

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

Фрустрация

На данный момент, я думаю, совершенно очевидно, что новичкам было бы очень сложно использовать Create React App для учебных целей. Это лучше, чем создавать свою собственную конфигурацию Webpack? Конечно, но в 2020 году, я думаю, у нас есть лучшие варианты.

Действительно минимальное решение

Файловая структура Nano React App

Иногда (то есть часто) вы хотите быстро перейти в React и создать несколько компонентов без лишних движений. Вот почему был создан Nano React App. Он был построен на Parcel, упаковщике веб-приложений (наподобие, Webpack), который включает в себя множество умных настроек по умолчанию. Он также может быть намного быстрее, чем Webpack, если ваш компьютер имеет несколько ядер.

И чтобы дать вам представление о популярности Parcel, на момент написания статьи: у Parcel есть 29 753 звезды на Github, а у Webpack — 46 495 звезд. То есть это не какой-то непонятный проект.

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

Чего еще в нем нет? Помимо извлечения: нет линтинга, нет тестирования, нет service workers.

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

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

Попробуйте!

Чтобы использовать приложение Nano React, просто запустите:

Примечание: npx это команда, связанная с современными версиями Node, которые позволяют запускать двоичный файл без необходимости выполнять предварительно npm install.

Это распакует шаблон приложения в каталог по вашему выбору (my-app в данном случае). Мы поддерживаем те же преобразования Babel, которые вы получаете с помощью Create React App, поэтому вы можете свободно использовать свойства класса для методов компонентов из коробки.

Мы не запускаем для вас npm install, поэтому распаковка шаблона проекта происходит очень быстро. Также отсутствуют файлы package-lock.json или yarn.lock. Это было сделано специально, так как мы не хотим склонять вас в сторону использования yarn или npm. Спасибо за внимание!

Автор: Adrian Li

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

Топ-пост этого месяца:  Советы по проектированию и созданию многоязычных сайтов
Добавить комментарий