веб приложение на react что это
Начало работы с React
React использует синтаксис HTML-in-JavaScript под названием JSX (JavaScript и XML). Знание HTML и JavaScript поможет вам изучить JSX и лучше определить, связаны ли ошибки в вашем приложении с JavaScript или с более специфической областью React.
Настроить локальную среду разработки React, создать стартовое приложение и понять основы его работы.
Привет React
Для создания веб-приложений разработчики используют React в тандеме с ReactDOM. React and ReactDOM часто обсуждаются в том же пространстве и используются для решения тех же проблем, что и другие настоящие фреймворки для веб-разработки. Когда мы ссылаемся на React как на «фреймворк», мы подразумеваем это разговорное понимание.
Когда использовать
В отличие от других платформ, рассматриваемых в этом модуле, React не обязывает к строгим правилам в отношении соглашений о коде или организации файлов. Это позволяет командам договариваться, что для них более подходит, и структурировать React проект соответствующим образом. React может отвечать за одну кнопку, несколько частей или же весь пользовательский интерфейс приложения.
Хотя React можно использовать для небольших частей интерфейса, «зайти» в него не так просто, как, к примеру, в jQuery, или даже во Vue. Куда легче это сделать создав всё приложение с помощью React.
Кроме того, такие преимущества React-приложения, как написание интерфейсов с помощью JSX, требуют процесса компиляции. Добавление на сайт компилятора Babel приводит к более медленному выполнению кода, поэтому такие инструменты обычно настраиваются для процесса сборки. Да, возможно, у React есть серьёзные требования к инструментарию, но его можно освоить.
В этой статье основное внимание будет уделено использованию React для создания всего пользовательского интерфейса с помощью create-react-app, предоставляемого Facebook.
Как React использует JavaScript?
React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of JSX syntax. JSX extends JavaScript’s syntax so that HTML-like code can live alongside it. For example:
This heading constant is known as a JSX expression. React can use it to render that
Suppose we wanted to wrap our heading in a tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:
Note: The parentheses in the previous snippet aren’t unique to JSX, and don’t have any effect on your application. They’re a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:
However, this looks kind of awkward, because the tag that starts the expression is not indented to the same position as its corresponding closing tag.
Of course, your browser can’t read JSX without help. When compiled (using a tool like Babel or Parcel), our header expression would look like this:
It’s possible to skip the compilation step and use React.createElement() to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, popular tooling makes JSX-to-JavaScript compilation part of its setup process. You don’t have to configure compilation yourself unless you want to.
Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you’re comfortable with it, however, it will allow you build user interfaces more quickly and intuitively, and allow others to better understand your code base at a glance.
To read more about JSX, check out the React team’s JSX In Depth article.
Настройка вашего первого React приложения
There are many ways to use React, but we’re going to use the command-line interface (CLI) tool create-react-app, as mentioned earlier, which expedites the process of developing a React application by installing some packages and creating some files for you, handling the tooling described above.
Перед вами — React Modern Web App
Перед тем как начать собирать с нуля Modern Web App нужно разобраться, что такое — Современное Веб-Приложение?
Modern Web App (MWA) — приложение, придерживающееся всех современных веб-стандартов. Среди них Progressive Web App — возможность скачивать мобильную браузерную версию на телефон и использовать как полноценное приложение. Так же это возможность листать сайт в оффлайне как с мобильного устройства, так и с компьютера; современный материальный дизайн; идеальная поисковая оптимизация; и естественно — высокая скорость загрузки.
Вот что будет в нашем MWA (советую использовать эту навигацию по статье):
Люди на Хабре деловые, поэтому сразу ловите ссылку на GitHub репозиторий, архив с каждой из стадий разработки и демо. Статья рассчитана на разработчиков, знакомых с node.js и react. Вся необходимая теория представлена в необходимом объеме. Расширяйте кругозор, переходя по ссылкам.
1. Universal
Выполняем npm install и, пока устанавливается, разбираемся.
Поскольку мы находимся на рубеже 2018 и 2019 года, наше веб-приложение будет универсальным (или изоморфным), — как на бэке, так и на фронте будет ECMAScript версии не ниже ES2017. Для этого index.js (входной файл приложения) подключает babel/register, и весь ES код, идущий за ним, babel на лету превращает в JavaScript, понятный браузеру, с помощью babel/preset-env и babel/preset-react. Для удобства разработки я обычно использую плагин babel-plugin-root-import, с помощью которого все импорты из корневой директории будут выглядеть как ‘
/’, а из src/ — ‘&/’. В качестве альтернативы вы можете прописывать длинные пути или использовать alias’ы из webpack’а.
Время настраивать Webpack. Создаем webpack.config.js и используем код (здесь и далее обращайте внимание на комментарии в коде).
С этого момента начинается самое интересное. Пора разработать серверную часть приложения. Server-side Rendering (SSR) — это технология, призванная в разы ускорить загрузку веб-приложения и решить вечный спор насчет поисковой оптимизации в Single Page Application (SEO в SPA). Для этого мы берем HTML-шаблон, засовываем в него контент и отправляем пользователю. Сервер делает это очень быстро — страница отрисовывается за считанные миллисекунды. Однако на сервере нет возможности манипулировать DOM’ом, поэтому клиентская часть приложения обновляет страницу, и она наконец-то становится интерактивной. Понятно? Разрабатываем!
Файл server/server.js собирает контент, сгенерированный react, и передает его в HTML-шаблон — /server/template.js. Стоит уточнить, что на сервере используется именно статический роутер, потому что мы не хотим менять url страницы во время загрузки. А react-helmet — библиотека, сильно упрощающая работу с метаданными (да и в целом с тегом head).
В server/template.js в голове выводим данные из helmet, подключаем фавикон, стили из статической директории /assets. В теле — контент и webpack бандл client.js, находящийся в папке /public, но так как она статическая — обращаемся по адресу корневой директории — /client.js.
Переходим к простому — клиентская часть. Файл src/client.js восстанавливает сгенерированный сервером HTML, не обновляя DOM, и делает его интерактивным. (Подробнее об этом здесь). Этим занимается react-функция hydrate. И теперь нам не за чем делать статичный роутер. Используем обычный — BrowserRouter.
Уже в двух файлах успел засветиться react-компонент App. Это главный компонент desktop-приложения, выполняющий роутинг. Его код весьма банален:
Ну и src/app/Home.js. Заметьте, как работает Helmet — обычная обертка тега head.
Поздравляю! Мы разобрали первую часть разработки MWA! Осталась лишь пара штрихов для того, чтобы все это дело протестировать. В идеале можете заполнить папку /assets файлами глобальных стилей и фавиконом соответственно шаблону — server/template.js. Еще у нас нет команд запуска приложения. Вернемся к package.json:
2. Material-ui
Эта часть туториала будет посвящена подключению к веб-приложению с SSR библиотеки material-ui. Почему именно она? Все просто — библиотека активно развивается, поддерживается, имеет широкую документацию. С ней можно строить красивый пользовательский интерфейс как раз плюнуть.
Сама схема подключения, подходящая нашему приложению, описана здесь. Что ж, let’s do it.
Устанавливаем необходимые зависимости:
Дальше нам предстоит внести изменения в уже существующие файлы. В server/server.js мы оборачиваем наше приложение в JssProvider и MuiThemeProvider, которые будут предоставлять material-ui компоненты и, что очень важно, объект sheetsRegistry — css, который необходимо поместить в HTML шаблон. На клиентской стороне используем только MuiThemeProvider, снабжая его объектом темы.
Теперь предлагаю добавить немного стильного дизайна в компонент Home. Все компоненты material-ui можете посмотреть на их официальном сайте, здесь же хватит Paper, Button, AppBar, Toolbar и Typography.
Теперь должно получиться что-то похожее:
3. Code Splitting
Если вы планируете писать что-то большее, чем TODO лист, то ваше приложение будет увеличиваться пропорционально бандлу client.js. Чтобы избежать долгой загрузки страниц у пользователя, уже давно придуман code splitting. Однако однажды Ryan Florence, один из создателей React-router, отпугнул потенциальных разработчиков своей фразой:
Godspeed those who attempt the server-rendered, code-split apps.
Удачи всем, кто решит создать ssr приложения с code splitting
Мы с вами отбитые — сделаем! Устанавливаем необходимое:
Одновременно с этим изменяем глобальный файл babel-конфигурации .babelrc
Здесь появилась react-loadable. Это библиотека с отличной документацией соберет все разбитые импортом webpack’а модули на сервере, а клиент с такой же легкостью подхватит их. Для этого нужно серверу загрузить все модули:
Сами же модули подключить очень просто. Взгляните на код:
React-loadable асинхронно загружает компонент Home, давая понять webpack’у, что он должен называться именно Home (да, это редкий случай, когда комментарии несут какой-то смысл). delay: 300 означает, что если через 300мс компонент все еще не загрузится, нужно показать, что загрузка все же идет. Этим занимается Loading:
Чтобы дать понять серверу, какие именно модули мы импортируем, нам нужно было бы прописать:
Но, чтобы не повторят один и тот же код, существует react-loadable/babel плагин, который мы уже успешно подключили в .babelrc. Теперь, когда сервер знает, что импортировать, нужно узнать, что же будет отрендерено. Схема работы немного напоминает Helmet:
Чтобы убедиться, что клиент загружает все модули, отрендеренные на сервере, нам нужно соотнести их с бандлами, созданными by webpack. Для этого внесем изменения в конфигурацию сборщика. Плагин react-loadable/webpack выписывает все модули в отдельный файл. Еще нам стоит сказать webpack’у, чтобы он правильно сохранял модули после динамического импорта — в объекте output.
Прописываем модули в шаблоне, загружая их по очереди:
Осталось лишь обработать клиентскую часть. Метод Loadable.preloadReady() загружает все модули, которые заранее отдал пользователю сервер.
Готово! Запускаем и смотрим на результат — в прошлой части бандлом был лишь один файл — client.js весом 265кб, а теперь — 3 файла, наибольший из которых весит 215кб. Стоит ли говорить, что скорость загрузки страницы значительно вырастет при масштабировании проекта?
4. Redux счетчик
Теперь мы приступим к решению практических задач. Как решить дилемму, когда у сервера есть данные (скажем, из базы данных), надо вывести их на экран для того, чтобы поисковые роботы смогли найти контент, а затем использовать эти данные на клиенте.
Решение есть. Оно используется почти в каждой статье по SSR, однако то, как это реализовано там, далеко не всегда поддается хорошей масштабируемости. Простыми словами, следуя большинству туториалов, вам не удастся сделать реальный сайт с SSR по принципу «Раз, два, и в продакшн». Сейчас попробую расставить точки над i.
Выполним действия, описанные выше. Тут по большей части повторение ранее использованного кода.
Получаем store на клиенте. src/client.js
Логика redux в SSR закончилась. Теперь обычная работа с redux — создание стора, экшены, редьюсеры, коннект и прочее. Надеюсь, что это будет понятно без особых объяснений. Если нет, почитайте документацию.
Такой результат кропотливой работы:
5. Мобильная версия
Теперь мы будем разрабатывать то, что нужно каждому современному сайту в обязательном порядке — мобильную версию. Делается это даже проще чем могло казаться. Нам нужно на сервере определить устройство пользователя и, в зависимости от этого, передавать ему нужную версию приложения с помощью initialState, который мы создали в прошлом разделе.
Установим последнюю за статью зависимость:
mobile detect определяет браузер юзера по заголовку user-agent, выдает null на десктопы и подробную информацию об устройстве и браузере в случае мобильного устройства.
Работаем с сервером:
Чтобы сотый раз не повторять один и тот же файл — полезай внутрь:
Теперь работенка осталась только для верстальщика или ленивого react-разработчика, любителя вставлять готовые красивые компоненты. Чтобы было чуть интереснее, добавил в мобильную версию роутинг. Посмотреть этот код можете в директории src/mobileApp здесь.
6. Прогрессивное приложение
Progressive Web App (PWA), по словам Google — это привлекательные, быстрые и надежные приложения, устанавливаемые на устройстве пользователя, управляемые в оффлайне.
Насчет устройств пользователя нужно внести ясность. На девайсах с андроидом у вас не будет проблем: современные Chrome, Opera и Samsung Internet сами предложат вам установить приложение, если оно соответствует требованиям. На iOS вы можете добавить приложение на главный экран только если зайдете в дебри Safari, однако это еще не гарантирует качественной работы. Как разработчику, вам нужно будет учесть некоторые факторы. На десктопах уже можно установить PWA: на Windows с Chrome v70, Linux с v70, ChromeOS с v67. Ожидаем PWA на macOS — предварительно такая возможность станет доступна в первой половине 2019 года с приходом Chrome v72.
Разработчикам нужно не так уж много сделать: PWA можно интегрировать на любой сайт без особых затрат. Только постарайтесь, чтобы ваш сайт имел мобильную версию или, по крайней мере, адаптивный дизайн.
2 файла — manifest.json и service-worker.js — наша необходимость. Манифест — это json файл, объясняющий, как приложение должно вести себя, когда установлено. Service-worker делает все остальное: управляет хешем и push-уведомлениями, перехватывает и модифицирует сетевые запросы и многое другое.
Начнем с манифеста. Описание всех директив почитайте по ссылкам, тут же будет самое важное:
Советую ознакомиться с отличным туториалом по написанию service-worker’а, потому что дело это не из самых легких. Смотрите внимательно на код, поддерживающий установку, кэширование и обновление:
Чтобы окончательно заставить PWA работать, нужно подключить манифест и регистрацию сервис-воркера к html-шаблону:
Готово! Если подключить к приложению https, то браузер предложит установить приложение, как это показано на gif выше в случае с demo.
7. Конец
На этом заканчивается повествование о разработке чудесного MWA. За эту нереальную статью успели разобрать, как с нуля создать приложение, дающее фору большинству шаблонных. Теперь вам незачем искать в Гугле, как связать между собой SSR и Code Splitting, как в два шага сделать PWA и как передавать данные с сервера на клиент при серверном рендере.
Кстати, вот такую статистику по MWA выдает недавно созданный веб-сайт web.dev:
Если ты внимательно прочитал эту статью, ты — монстр. Можешь плюсануть, поддержать звездочкой на гитхабе, хотя самая лучшая поддержка — это максимальная эксплуатация моего кода.
Кстати, MWA — opensource проект. Используйте, распространяйте, улучшайте!
Основы React: всё, что нужно знать для начала работы
Хотите узнать о том, что такое React, но вам всё никак не выпадает шанс изучить его? Или, может быть, вы уже пробовали освоить React, но не смогли толком понять? А может, вы разобрались с основами, но хотите привести в порядок знания? Эта статья написана специально для тех, кто положительно ответил хотя бы на один из этих вопросов. Сегодня мы создадим простой музыкальный проигрыватель, раскрывая основные концепции React по мере продвижения к цели.
Разобравшись с этим материалом, вы освоите следующее:
Предварительная подготовка
Рассмотрим такую ситуацию: к вам за помощью обращается маленький стартап. Они создали приятную страницу, пользуясь которой пользователи могут загружать в их сервис музыку и проигрывать её. Им хочется, чтобы вы сделали самое сложное — вдохнули в эту страницу жизнь.
Для начала создайте новую директорию проекта и добавьте туда три файла. Вот они на GitHub, а вот их код.
Для успешного прохождения этого руководства вам понадобится свежая версия браузера Google Chrome, иначе не будут работать анимации. Выражаем благодарность Стивену Фабре за CSS для кнопки проигрывания и Джастину Виндлу за код визуализации (оригинал можно посмотреть здесь).
Откройте index.html в редакторе кода и в браузере. Пришло время познакомиться с React.
Что такое React?
React — это инструмент для создания пользовательских интерфейсов. Его главная задача — обеспечение вывода на экран того, что можно видеть на веб-страницах. React значительно облегчает создание интерфейсов благодаря разбиению каждой страницы на небольшие фрагменты. Мы называем эти фрагменты компонентами.
Вот пример разбивки страницы на компоненты:
Каждый выделенный фрагмент страницы, показанной на рисунке, считается компонентом. Но что это значит для разработчика?
Что такое компонент React?
Компонент React — это, если по-простому, участок кода, который представляет часть веб-страницы. Каждый компонент — это JavaScript-функция, которая возвращает кусок кода, представляющего фрагмент страницы.
Для формирования страницы мы вызываем эти функции в определённом порядке, собираем вместе результаты вызовов и показываем их пользователю.
Напишем компонент внутри тега
Функции можно писать и так:
React использует язык программирования, называемый JSX, который похож на HTML, но работает внутри JavaScript, что отличает его от HTML.
Вы можете добавить сюда обычный HTML для того, чтобы он попал в пользовательский интерфейс:
Можно и написать собственный компонент на JSX. Делается это так:
Это — стандартный подход — вызывать компоненты так, будто вы работаете с HTML.
Сборка компонентов
Компоненты React можно помещать в другие компоненты.
Вот что выведет вышеприведённый код:
Именно так страницы собирают из фрагментов, написанных на React — вкладывая компоненты друг в друга.
Классы компонентов
До сих пор мы писали компоненты в виде функций. Их называют функциональными компонентами. Однако, компоненты можно писать и иначе, в виде классов JavaScript. Их называют классами компонентов.
В том случае, если вас интересуют компоненты без состояния, предпочтение следует отдать функциональным компонентам, их, в частности, легче читать. О состоянии компонентов мы поговорим ниже.
JavaScript в JSX
В JSX-код можно помещать переменные JavaScript. Выглядит это так:
Теперь текст «I am a string» окажется внутри тега
Кроме того, тут можно делать и вещи посложнее, вроде вызовов функций:
Вот как будет выглядеть страница после обработки вышеприведённого фрагмента кода:
Подводные камни JSX
Для того, чтобы этого добиться, нужно воспользоваться свойством className :
Особенности создаваемого компонента
Метод constructor компонента React всегда должен вызвать super(props) прежде чем выполнять что угодно другое.
Итак, а что нам делать с этим «состоянием»? Зачем оно придумано?
Изменение компонента React на основе его состояния
Состояние — это инструмент, позволяющий обновлять пользовательский интерфейс, основываясь на событиях. Тут мы будем использовать состояние для изменения внешнего вида кнопки проигрывания музыки, основываясь на щелчке по ней. Кнопка может отображаться в одном из двух вариантов. Первый указывает на возможность запуска проигрывания, второй — на то, что музыка проигрывается, и этот процесс можно приостановить. Когда пользователь щёлкает по кнопке, меняется состояние, а затем обновляется пользовательский интерфейс.
В функции render ключевое слово this всегда ссылается на компонент, внутри которого она находится.
Как компонент реагирует на события?
Пользователь может взаимодействовать с компонентом, щёлкая по кнопке проигрывания музыки. Мы хотим реагировать на эти события. Делается это посредством функции, которая занимается обработкой событий. Эти функции так и называются — обработчики событий.
Когда пользователь щёлкает по тексту, представленному тегом
Как должен работать компонент
Теперь, разобравшись с этим механизмом, займёмся обработкой щелчка по кнопке.
Обмен данными между компонентами
Когда состояние Container меняется, свойство PlayButton также меняется, и функция PlayButton вызывается снова. Это означает, что вид компонента на экране обновится.
Внутри PlayButton мы можем реагировать на изменения, так как PlayButton принимает свойства как аргумент:
Если мы поменяем состояние на this.state = < isMusicPlaying: true >; и перезагрузим страницу, на ней должна появиться кнопка паузы:
События как свойства
Свойства необязательно должны представлять собой какие-то данные. Они могут быть и функциями.
Неприятная особенность setState
Поэтому вот так поступать не следует:
Если вы изменяете состояние, основываясь на предыдущем состоянии, нужно делать это по-другому. А именно, следует передать setState функцию, а не объект. Эта функция принимает старое состояние как аргумент и возвращает объект, представляющий новое состояние.
Эта конструкция сложнее, но она необходима только в том случае, если вы используете старое состояние для формирования нового состояния. Если нет — можно просто передавать setState объект.
Что такое ссылки?
Пришло время включить музыку. Для начала добавим тег :
React.js: понятное руководство для начинающих
Автор статьи, перевод которой мы публикуем, считает, что, к несчастью, в большинстве из существующих руководств по React не уделяется должного внимания ценным практическим приёмам разработки. Такие руководства не всегда дают тому, кто по ним занимается, понимание того, что такое «правильный подход» к работе с React.
В этом руководстве, которое рассчитано на начинающих разработчиков, имеющих знания в области HTML, JavaScript и CSS, будут рассмотрены основы React и самые распространённые ошибки, с которыми может столкнуться программист, пользующийся данной библиотекой.
Почему веб-разработчики выбирают React?
Прежде чем мы приступим к делу, скажем пару слов о том, почему React можно считать наилучшей альтернативой среди средств для разработки веб-интерфейсов. Существует множество UI-фреймворков. Почему стоит выбрать именно React? Для того чтобы ответить на этот вопрос — сравним два самых популярных инструмента для разработки интерфейсов — React и Angular. Надо отметить, что в это сравнение можно было бы включить и набирающий популярность фреймворк Vue.js, но мы ограничимся React и Angular.
▍Декларативный подход к описанию интерфейсов
React-разработка заключается в описании того, что нужно вывести на страницу (а не в составлении инструкций для браузера, посвящённых тому, как это делать). Это, кроме прочего, означает значительное сокращение объёмов шаблонного кода.
В составе Angular, с другой стороны, есть средства командной строки, которые генерируют шаблонный код компонентов. Не кажется ли это немного не тем, чего можно ждать от современных инструментов разработки интерфейсов? Фактически, речь идёт о том, что в Angular так много шаблонного кода, что для того, чтобы его генерировать, даже создано специальное средство.
В React, приступая к разработке, просто начинают писать код. Тут нет шаблонного кода компонентов, который нужно как-то генерировать. Конечно, перед разработкой нужна некоторая подготовка, но, когда дело доходит до компонентов, их можно описывать в виде чистых функций.
▍Чёткий синтаксис
▍Правильная кривая обучения
Кривая обучения — это важный фактор, который нужно учитывать при выборе UI-фреймворка. В этой связи надо отметить, что в React имеется меньше абстракций, чем в Angular. Если вы знаете JavaScript, то, вероятно, вы сможете научиться писать React-приложения буквально за день. Конечно, для того, чтобы научиться делать это правильно, потребуется некоторое время, но приступить к работе можно очень и очень быстро.
Если же проанализировать Angular, то окажется, что если вы решите освоить этот фреймворк, вам придётся изучить новый язык (Angular использует TypeScript), а также научиться использовать средства командной строки Angular и привыкнуть к работе с директивами.
▍Особенности механизма привязки данных
В Angular имеется система двусторонней привязки данных. Это, например, выражается в том, что изменения в форме элемента приводят к автоматическому обновлению состояния приложения. Это усложняет отладку и является большим минусом данного фреймворка. При таком подходе, если что-то идёт не так, программист не может совершенно точно знать о том, что именно стало причиной изменения состояния приложения.
В React, с другой стороны, используется односторонняя привязка данных. Это — большой плюс данной библиотеки, так как выражается это в том, что программист всегда точно знает о том, что привело к изменению состояния приложения. Подобный подход к привязке данных значительно упрощает отладку приложений.
▍Функциональный подход к разработке
Я полагаю, что одной из сильнейших сторон React является тот факт, что эта библиотека не принуждает разработчика к использованию классов. В Angular же все компоненты должны быть реализованы в виде классов. Это приводит к чрезмерному усложнению кода, не давая никаких преимуществ.
В React все компоненты пользовательского интерфейса могут быть выражены в виде наборов чистых функций. Использование чистых функций для формирования UI можно сравнить с глотком чистого воздуха.
Теперь, когда мы рассмотрели причины популярности React, которые, вполне возможно, склонят вас в сторону именно этой библиотеки при выборе инструментов для разработки пользовательских интерфейсов, перейдём к практике.
Практика разработки React-приложений
▍Node.js
Node.js — это серверная платформа, поддерживающая выполнение JavaScript-кода, возможности которой пригодятся нам для React-разработки. Если эта платформа ещё у вас не установлена — сейчас самое время это исправить.
▍Подготовка проекта
Здесь мы, для создания основы React-приложения, будем использовать пакет create-react-app от Facebook. Вероятно, это самый популярный подход к настройке рабочего окружения, которое позволяет приступить к разработке. Благодаря create-react-app программист получает в своё распоряжение множество нужных инструментов, что избавляет его от необходимости самостоятельно их подбирать.
Затем, для создания шаблона приложения, выполните такую команду:
На этом предварительная подготовка закончена. Для запуска приложения выполните следующие команды:
Тут мы переходим в папку проекта и запускаем сервер разработки, который позволяет открыть новое React-приложение, перейдя в браузере по адресу http://localhost:3000/.
▍Структура проекта
Разберёмся теперь с тем, как устроено React-приложение. Для этого откройте только что созданный проект с помощью вашей IDE (я рекомендую Visual Studio Code).
Файл index.html
Здесь нас особенно интересует строка
. Именно тут будет находиться наше React-приложение. Весь этот элемент будет заменён на код приложения, а всё остальное останется неизменным.
Файл index.js
Вот строка кода, которая ответственна за вывод того, что мы называем «React-приложением», на страницу:
Файл App.js
Обратите внимание на то, что атрибут className — это эквивалент атрибута class в HTML. Он используется для назначения элементам CSS-классов в целях их стилизации. Ключевое слово class в JavaScript является зарезервированным, его нельзя использовать в качестве имени атрибута.
Повторим то, что мы только что выяснили о компонентах:
▍Рекомендация №1: не нужно везде использовать классы компонентов
Компоненты в React можно создавать, применяя два подхода. Первый заключается в использовании классов компонентов (Class Component), второй — в использовании функциональных компонентов (Functional Component). Как вы, возможно, заметили, в вышеприведённом примере используются классы. К сожалению, большинство руководств по React для начинающих предлагают использовать именно их.
Что плохого в описании компонентов с использованием механизма классов? Дело в том, что такие компоненты тяжело тестировать и они имеют свойство чрезмерно разрастаться. Эти компоненты подвержены проблеме некачественного разделения ответственности, смешиванию логики и визуального представления (а это усложняет отладку и тестирование приложений). В целом, использование классов компонентов ведёт к тому, что программист, фигурально выражаясь, «стреляет себе в ногу». Поэтому, особенно если речь идёт о начинающих программистах, я порекомендовал бы им совсем не пользоваться классами компонентов.
Видите, что мы тут сделали? А именно, мы убрали класс и заменили метод render конструкцией вида function App() <. >. Если же тут воспользоваться синтаксисом стрелочных функций ES6, то наш код будет выглядеть ещё лучше:
Мы превратили класс в функцию, возвращающую разметку, которую надо вывести на страницу.
Поразмыслите над этим. В функции, которая возвращает разметку, нет шаблонного кода. Это — практически чистая разметка. Разве это не прекрасно?
Код функциональных компонентов гораздо легче читать, работая с ними, приходится гораздо меньше отвлекаться на стандартные конструкции.
Тут надо отметить, что хотя только что мы сказали о том, что функциональные компоненты предпочтительнее классов компонентов, в этом материале мы будем пользоваться, в основном, классами, так как код классов компонентов оказывается понятнее для новичков, он полагается на меньшее количество абстракций, с его помощью легче демонстрировать ключевые концепции React. Но когда вы в достаточной мере освоитесь в деле разработки React-приложений, настоятельно рекомендуется учитывать, при разработке реальных проектов, то, что было сказано выше. Для того чтобы лучше разобраться с функциональными компонентами — взгляните на этот материал.
▍Знакомство со свойствами
Свойства (props) — это одна из центральных концепций React. Что такое «свойства»? Для того чтобы это понять, вспомните о параметрах, которые передают функциям. В сущности, свойства — это и есть параметры, которые передаются компонентам. Рассмотрим следующий код:
Код можно упростить, воспользовавшись возможностями ES6 по деструктурированию объектов:
Что если для решения такой же задачи мы, вместо функциональных компонентов, использовали бы компоненты, основанные на классах? В таком случае код компонента Greetings выглядел бы так:
▍Принцип единственной ответственности
Принцип единственной ответственности (Single Responsibility Principle, SRP) — это один из важнейших принципов программирования, которого следует придерживаться. Он говорит нам о том, что модуль должен решать только одну задачу и должен делать это качественно. Если разрабатывать проект, не следуя только одному этому принципу, код такого проекта может превратиться в кошмарную конструкцию, которую невозможно поддерживать.
Как можно нарушить принцип единственной ответственности? Чаще всего это происходит тогда, когда несвязанные друг с другом механизмы размещают в одних и тех же файлах. В этом материале мы часто будем обращаться к данному принципу.
Новички обычно размещают в одном файле множество компонентов. Например, у нас код компонентов Greetings и App находится в одном файле. На практике так поступать не следует, так как это нарушает SRP.
Даже очень маленькие компоненты (вроде нашего компонента Greetings ) нужно размещать в отдельных файлах.
Поместим код компонента Greetings в отдельный файл:
Затем воспользуемся этим компонентом в компоненте App :
▍Знакомство с состоянием приложения
Состояние (state) — это ещё одна из центральных концепций React. Именно здесь хранятся данные приложения — то есть то, что может меняться. Нужно сохранить что-то, введённое в поле формы? Используйте состояние. Нужно сохранить очки, набранные игроком в браузерной игре? Для этого тоже надо использовать состояние приложения.
Создадим простую форму, с помощью которой пользователь может ввести своё имя. Обратите внимание на то, что здесь я намеренно использую для описания компонента класс, так как это облегчает демонстрацию рассматриваемой концепции. О том, как преобразовать компонент, созданный с использованием класса, в функциональный компонент, можете почитать здесь.
Как использовать значение, введённое в поле? В React не полагается обращаться к элементам DOM напрямую. Решить эту задачу нам помогут обработчики событий и состояние приложения.
В данном случае event.target.value — это то, что пользователь ввёл в поле формы, а именно — его имя.
Обратите внимание на то, что мы не объявили onFirstNameChange в виде метода. Очень важно, чтобы подобные вещи объявлялись бы в виде свойств класса, содержащих стрелочные функции, а не в виде методов. Если объявить подобную функцию в виде метода, тогда this будет привязано к элементу формы, который вызывает этот метод, а не к классу, как мы могли бы ожидать. Эта мелочь часто сбивает с толку новичков. Это — одна из причин рекомендации по использованию функциональных компонентов, а не классов компонентов.
▍Проверка данных, введённых в форму
Реализуем простую систему проверки данных, введённых в форму, используя регулярные выражения. Давайте решим, что имя должно состоять как минимум из трёх символов и может содержать лишь буквы.
Состояние приложения
Разрабатывая систему проверки ввода, мы, для начала, добавили в состояние новое свойство: firstNameError :
Функция проверки данных
Если проверка не удалась — мы возвращаем из функции сообщение об ошибке. Если имя прошло проверку — возвращаем пустую строку, которая указывает на то, что ошибок при проверке имени не найдено. Тут мы, ради краткости кода, пользуемся тернарным оператором JavaScript.
Обработчик события onBlur
Метод render
Рассмотрим метод компонента render() :
Тут мы снова пользуемся деструктурирующим присваиванием для извлечения данных из состояния.
▍Стилизация
Если вы воспроизводили у себя то, о чём мы тут говорили, то вы могли заметить, что наша форма выглядит не слишком симпатично. Давайте это исправим, воспользовавшись встроенными стилями:
Признаю, что я не дизайнер, но то, что у меня получилось, выглядит сейчас гораздо лучше, чем прежде. Вот какой стала теперь форма, в которой выводится сообщение об ошибке.
Стилизованная форма с сообщением об ошибке
▍Рекомендация №2: избегайте использования стилей внутри компонентов
После того, как этот файл создан, подключим его в компоненте SimpleComponent :
Этот код выглядит куда чище, чем его предыдущий вариант. Поэтому примите себе за правило размещать стили в отдельных файлах.
▍Добавление полей формы
Сделаем нашу форму немного интереснее, добавив в неё поле для ввода фамилии пользователя:
В обновлённом компоненте не так уж и много изменений — мы просто скопировали код, используемый для описания firstName и создали копии обработчиков событий.
Неужто это я написал слово «скопировали»? Копирование кода — это то, чего стоит всеми силами избегать.
▍Рекомендация №3: разделяйте код на небольшие фрагменты
Монолитный код, не разделённый на части, это проблема, которая, как и многие другие, нарушает принцип единственной ответственности. Хорошо написанный код должен читаться как поэма, а я готов поспорить, что код метода render нашего компонента выглядит куда хуже. Займёмся решением этой проблемы.
Я, создавая этот компонент, просто извлёк код одного из полей ввода из метода render и оформил его в виде функционального компонента. То, что в разных экземплярах подобного компонента может меняться, передано ему в виде свойств.
Вот как можно использовать этот новый компонент в компоненте SimpleForm :
Такой код читать легче, чем прежний. Мы можем пойти ещё дальше, создав отдельные компоненты TextField для имени и фамилии. Вот код компонента FirstNameField :
Похожим образом устроен и компонент LastNameField :
Вот каким теперь будет код формы:
Теперь код компонента выглядит гораздо лучше.
▍О классах компонентов
Перечислим причины, по которым не рекомендуется использовать компоненты, основанные на классах, отдавая предпочтение функциональным компонентам:
Итоги
Хотя этот материал и получился достаточно длинным, о создании React-приложений можно говорить ещё очень долго. В частности, о том, как правильно организовывать код, и о том, какие приёмы разработки рекомендуется и не рекомендуется использовать. Несмотря на то, что это руководство не является всеобъемлющим, мы полагаем, что если благодаря ему состоялось ваше первое знакомство с React, то вы, пользуясь тем, что сегодня узнали, сможете эффективно осваивать эту UI-библиотеку.
→ Исходный код примеров, рассмотренных в этом материале, можно найти здесь
Уважаемые читатели! Если сегодня, в ходе прочтения этой статьи, вы написали свои первые строки React-кода, просим поделиться впечатлениями.