React — замечательная библиотека JavaScript, которая покорила сообщество разработчиков. Короче говоря, разработчикам стало проще создавать интерактивные пользовательские интерфейсы для веб-, мобильных и настольных платформ. Сегодня тысячи компаний по всему миру используют React, включая такие известные компании, как Netflix и Airbnb.
В этом руководстве я познакомлю вас с React и несколькими его фундаментальными концепциями. Мы быстро начнем работу с инструментом Create React App, а затем шаг за шагом пройдем процесс создания простого приложения React. К тому времени, когда вы закончите, у вас будет хороший обзор основ, и вы будете готовы сделать следующий шаг в своем путешествии по React.
Предпосылки
Прежде чем приступить к изучению React, имеет смысл иметь базовое представление о HTML, CSS и JavaScript. Это также поможет иметь базовое представление о Node.js, а также о менеджере пакетов npm.
Чтобы следовать этому руководству, вам потребуются установленные на вашем компьютере Node и npm. Для этого перейдите на страницу загрузки Node.js и скачайте нужную версию (npm поставляется вместе с Node). Кроме того, вы можете ознакомиться с нашим руководством по установке Node с помощью диспетчера версий.
Что такое Реакт?
React — это библиотека JavaScript для создания компонентов пользовательского интерфейса. В отличие от более полных фреймворков, таких как Angular или Vue, React работает только со слоем представления, поэтому вам потребуются дополнительные библиотеки для обработки таких вещей, как маршрутизация, управление состоянием и т. д. В этом руководстве мы сосредоточимся на том, что React может делать из коробки.
Приложения React создаются с использованием многократно используемых компонентов пользовательского интерфейса, которые могут взаимодействовать друг с другом. Компонент React может быть компонентом на основе класса или так называемым функциональным компонентом. Компоненты на основе классов определяются с помощью классов ES6, тогда как функциональные компоненты являются базовыми функциями JavaScript. Они, как правило, определяются с помощью функции стрелки, но они также могут использовать functionключевое слово. Компоненты на основе классов будут реализовывать renderфункцию, которая возвращает некоторый JSX (расширение React для обычного JavaScript, используемое для создания элементов React), тогда как функциональные компоненты будут возвращать JSX напрямую. Не волнуйтесь, если вы никогда не слышали о JSX, так как позже мы рассмотрим его подробнее.
Компоненты React можно далее разделить на компоненты с состоянием и без состояния. Работа компонента без состояния заключается в простом отображении данных, которые он получает от своего родительского компонента React. Если он получает
С другой стороны, компонент с отслеживанием состояния отвечает за поддержание определенного состояния приложения. Это может включать получение данных из внешнего источника или отслеживание того, вошел ли пользователь в систему или нет. Компонент с состоянием может реагировать на события и входные данные для обновления своего состояния.
Как правило, вы должны стремиться писать компоненты без состояния, где это возможно. Их легче повторно использовать как в приложении, так и в других проектах.
Понимание виртуального DOM
Прежде чем мы перейдем к кодированию, вам нужно знать, что React использует виртуальный DOM для обработки рендеринга страницы. Если вы знакомы с jQuery, то знаете, что он может напрямую манипулировать
Чтобы противостоять этому, была изобретена концепция Virtual DOM (представление реального DOM в памяти), которая в настоящее время применяется многими современными
Запустите пустой проект React
В соответствии с предварительными условиями я предполагаю, что у вас уже настроена среда Node с актуальной версией npm (или, при желании, Yarn).
Далее мы собираемся создать наше первое приложение React, используя Create React App, официальный служебный скрипт для создания одностраничных приложений React.
Давайте установим это сейчас:
npm i -g
Затем используйте его для создания нового приложения React.
В зависимости от скорости вашего
Если вы не хотите устанавливать слишком много пакетов по всему миру, вы также можете npx, что позволяет загружать и запускать пакет без его установки:
npx i -g
Запуск любой из этих команд должен вывести
...
Success! Created
Inside that directory, you can run several commands:
yarn start
Starts the development server.
yarn build
Bundles the app into static files for production.
yarn test
Starts the test runner.
yarn eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd
yarn start
Happy hacking!
После завершения процесса настройки проекта выполните следующие команды, чтобы запустить приложение React:
cd
npm start
Вы должны увидеть следующий вывод:
...
Compiled successfully!
You can now view
Local: http: //localhost:3000
On Your Network: http: //192.168.56.1:3000
Note that the development build is not optimized.
To create a production build, use yarn build.
Ваш браузер по умолчанию должен запуститься автоматически, и вы должны увидеть такой экран:
Создать
Теперь, когда мы подтвердили, что наш начальный проект React работает без ошибок, давайте посмотрим, что происходит внутри. Вы можете открыть папку
{
«name»: «
«version»: «0.1.0»,
«private»: true,
«dependencies»: {
«@
«@
«@
«react»: «^16.13.1»,
«
«
},
«scripts»: {
«start»: «
«build»: «
«test»: «
«eject»: «
},
«eslintConfig»: {
«extends»: «
},
«browserslist»: {
«production»: [
«>0.2%»,
«not dead»,
«not op_mini all»
],
«development»: [
«last 1 chrome version»,
«last 1 firefox version»,
«last 1 safari version»
]
}
}
Как видите, приложение Create React установило для нас несколько зависимостей. Первые три связаны с библиотекой тестирования React, которая (как вы могли догадаться) позволяет нам тестировать наш код React. Затем у нас есть reactи
Затем идут четыре
startзапускает сервер разработки
buildсоздает готовую к производству версию вашего приложения
testзапускает тесты, упомянутые выше
ejectоткроет среду разработки вашего приложения
Эта последняя команда заслуживает внимания. Инструмент Create React App обеспечивает четкое разделение между вашим реальным кодом и средой разработки. Если вы запустите npm run eject, приложение Create React перестанет скрывать то, что оно делает под капотом, и выгрузит все в package.jsonфайл вашего проекта. Хотя это дает вам более тонкий контроль над зависимостями вашего приложения, я бы не рекомендовал вам делать это, так как вам придется управлять всем сложным кодом, используемым при создании и тестировании вашего проекта. Если на то пошло, вы можете использовать
Приложение Create React также поставляется с поддержкой ESLint (как видно из eslintConfigсвойства) и настраивается с использованием правил ESLint для реактивного приложения.
Свойство browserslistфайла package.jsonпозволяет указать список браузеров, которые будет поддерживать ваше приложение. Эта конфигурация используется инструментами и транспилерами PostCSS, такими как Babel.
Одна из самых крутых функций, которые вам понравятся в приложении Create React, заключается в том, что оно обеспечивает горячую перезагрузку из коробки. Это означает, что любые изменения, которые мы вносим в код, вызовут автоматическое обновление браузера. Изменения в коде JavaScript перезагрузят страницу, а изменения в CSS обновят DOM без перезагрузки.
А пока давайте сначала остановим сервер разработки, нажав Ctrl+ C. После остановки сервера удалите все, кроме файлов serviceWorker.jsи в папке. Если вам интересно узнать, чем занимаются
Кроме того, мы создадим весь код с нуля, чтобы вы могли понять все, что находится внутри srcпапки.
Знакомство с синтаксисом JSX
JSX, определенный документацией React как «расширение синтаксиса для JavaScript», упрощает написание компонентов React. Используя JSX, мы можем передавать структуры HTML или элементы React, как если бы они были стандартными значениями JavaScript.
Вот краткий пример:
import React from ‘react’;
export default function App () {
const message = I’m a heading; //JSX FTW!
return (message) ;
}
Обратите внимание на строку const message = I’m a heading;. Это JSX. Если вы попытаетесь запустить это в
Примечание: вы можете узнать больше о JSX в нашем руководстве «Введение в JSX «.
Раньше файлы React JSX поставлялись с.jsxрасширением файла. В настоящее время инструмент Create React App создает файлы React с.jsрасширением файла. Хотя.jsxрасширение файла
В VS Code Emmet готов работать с.jsxфайлами. Однако вы можете настроить VS Code для обработки всех.jsфайлов так JavaScriptReact, чтобы Emmet работал с этими файлами.
Существуют разные правила линтинга для стандартного кода JavaScript и кода React JavaScript.
Однако в этом уроке я буду придерживаться того, что дает нам приложение Create React, и придерживаться окончания.jsфайла.
Привет, мир! в реакции
Приступим к написанию кода. Внутри srcпапки только что созданного файла
import React from ‘react’;
import ReactDOM from ‘
ReactDOM.render (Hello World, document.getElementById (‘root’));
Снова запустите сервер разработки, используя npm startили yarn start. Ваш браузер должен отображать следующее содержимое:
Привет Реагировать
Это самый простой пример React «Hello World». Этот index.jsфайл является корнем вашего проекта, в котором будут отображаться компоненты React. Позвольте мне объяснить, как работает код:
Строка 1: импортируется пакет React для обработки JSX.
Строка 2: пакет ReactDOM импортируется для рендеринга корневого компонента React.
Строка 3: Вызов функции рендеринга, передача:
Hello World: элемент JSX
document.getElementById (‘root’): контейнер HTML (здесь будет отображаться элемент JSX).
Контейнер HTML находится в public/index.htmlфайле. В строке 31 вы должны увидеть
. Это называется корневым узлом DOM, потому что все внутри него будет управляться виртуальным DOM React.
Хотя JSX очень похож на HTML, у него есть несколько ключевых отличий. Например, вы не можете использовать classатрибут, так как это ключевое слово JavaScript. Вместо этого classNameиспользуется вместо него. Кроме того, такие события, как onclickнаписаны onClickв JSX. Давайте теперь изменим наш код Hello World:
const element =
;
ReactDOM.render (element, document.getElementById (‘root’));
Я переместил код JSX в постоянную переменную с именем element. Я также заменил h1теги на divтеги. Чтобы JSX работал, вам нужно обернуть ваши элементы внутри одного родительского тега.
Взгляните на следующий пример:
const element = Hello, Jane;
Приведенный выше код не будет работать. Вы получите синтаксическую ошибку, указывающую на то, что вы должны заключить смежные элементы JSX в закрывающий тег.
const element =
Hello,
Jane
;
Как насчет оценки выражений JavaScript в JSX? Простой. Просто используйте фигурные скобки следующим образом:
const name = «Jane»;
const element = Hello, {name}
...или вот так:
const user = {
firstName: ‘Jane’,
lastName: ‘Doe’
}
const element = Hello, {user.firstName} {user.lastName}
Обновите свой код и убедитесь, что в браузере отображается «Привет, Джейн Доу». Попробуйте другие примеры, такие как { 5 + 2 }. Теперь, когда у вас есть основы работы с JSX, давайте продолжим и создадим компонент React.
Объявление компонентов React
Приведенный выше пример был упрощенным способом показать вам, как это ReactDOM.render () работает. Как правило, мы инкапсулируем всю логику проекта в компоненты React, которые затем передаются в ReactDOM.renderфункцию.
Внутри srcпапки создайте файл с именем App.jsи введите следующий код:
import React, { Component } from ‘react’;
class App extends Component {
render () {
return (
Hello World Again!
)
}
}
export default App;
Здесь мы создали компонент React, определив класс JavaScript, который является подклассом React.Component. Мы также определили функцию рендеринга, которая возвращает элемент JSX. Вы можете поместить дополнительный код JSX в
import React from ‘react’;
import ReactDOM from ‘
import App from '. /App’;
ReactDOM.render (
Сначала мы импортируем Appкомпонент. Затем мы визуализируем Appв формате JSX, например:
Далее мы рассмотрим, как применять стили.
Стилизация элементов JSX
Существуют различные способы стилизации компонентов React. Два, которые мы рассмотрим в этом уроке:
Встроенный стиль JSX
Внешние таблицы стилей
Ниже приведен пример того, как мы можем реализовать встроенный стиль JSX:
// src/App.js
render () {
const headerStyle = {
color: '#ff0000',
textDecoration: ‘underline’
}
return (
Hello World Again!
)
}
Стиль React очень похож на обычный CSS, но есть некоторые ключевые отличия. Например, headerStyleявляется литералом объекта. Мы не можем использовать точку с запятой, как обычно. Кроме того, несколько объявлений CSS были изменены, чтобы сделать их совместимыми с синтаксисом JavaScript. Например, вместо
Мы также можем реализовать стиль следующим образом:
// src/App.js
return (
Hello World Again!
)
Второй метод заключается в использовании внешних таблиц стилей. По умолчанию внешние таблицы стилей CSS уже поддерживаются. Если вы хотите использовать препроцессор, такой как Sass, обратитесь к документации, чтобы узнать, как его настроить.
Внутри srcпапки создайте файл с именем App.cssи введите следующий код:
h1 {
}
Добавьте следующий оператор импорта src/App.jsв начало файла:
import '. /App.css’;
После сохранения вы должны увидеть, что текстовое содержимое в вашем браузере резко изменилось в размере. Вы также можете использовать классы CSS следующим образом:
.
color: #ff0000;
}
Обновить src/App.jsследующим образом:
Hello World Again!
Мы не можем использовать classатрибут HTML, так как это зарезервированное ключевое слово JavaScript. Вместо этого мы используем className. Ниже должен быть ваш ожидаемый результат.
Стилизация в React
Теперь, когда вы узнали, как добавить стили в свой проект React, давайте продолжим и узнаем о компонентах React без состояния и с состоянием.
Компоненты без состояния и компоненты с состоянием
Компонент без сохранения состояния, также известный как тупой компонент, — это просто компонент, который отображает информацию. Он не содержит никакой логики для манипулирования данными. Он может получать события от пользователя, которые затем передаются в родительский контейнер для обработки.
Создайте файл
import React from ‘react’;
class MessageView extends React.Component {
render () {
return (
From:
John Doe
Status:
Unread
Message:
Have a great day!
)
}
}
export default MessageView;
Затем добавьте базовые стили src/App.cssс помощью следующего кода:
body {
color: #2D3748;
}
h1 {
}
.container {
width: 800px;
margin: 0 auto;
}
.message {
width: 400px;
padding: 12px;
}
.field{
display: flex;
}
.label {
width: 6rem;
}
.value {
color: #4A5568;
}
.content.value {
}
Наконец, измените src/App.jsтак, чтобы весь файл выглядел так:
import React, { Component } from ‘react’;
import '. /App.css’;
import MessageView from '. /
class App extends Component {
render () {
return (
)
}
}
export default App;
К настоящему времени код должен быть довольно понятным, так как я уже объяснял задействованные концепции. Теперь взгляните на свой браузер, и вы должны увидеть следующий результат:
Просмотр сообщений
Ранее мы упоминали, что React предлагает как классовые, так и функциональные компоненты. Мы можем переписать MessageView, используя функциональный синтаксис следующим образом:
import React from ‘react’;
export default function MessageView () {
return (
From:
John Doe
Status:
Unread
Message:
Have a great day!
) ;
}
Обратите внимание, что я удалил Componentимпорт, так как это не требуется в функциональном синтаксисе. Поначалу этот стиль может сбивать с толку, но вы быстро научитесь писать компоненты React таким образом.
Также с появлением хуков React этот стиль написания компонентов React становится все более популярным.
Передача данных через реквизиты
Вы успешно создали компонент React без сохранения состояния. Однако он не завершен, поскольку необходимо проделать еще немного работы, чтобы правильно интегрировать его с компонентом или контейнером с отслеживанием состояния. В настоящее время MessageViewотображаются статические данные. Нам нужно изменить его, чтобы он мог принимать входные параметры. Мы делаем это, используя так называемые реквизиты — данные, которые мы собираемся передать от родительского компонента.
Начните с изменения MessageViewкомпонента следующим образом:
import React from ‘react’;
class MessageView extends React.Component {
render () {
const message = this.props.message;
return (
From:
{message.from}
Status:
{message.status}
Message:
{message.content}
)
}
}
export default MessageView;
Здесь главное знать, как мы определяем messageпеременную. Мы присваиваем ему значение this.props.message, которое мы будем передавать от родительского компонента с отслеживанием состояния. Затем в нашем JSX мы можем сослаться на нашу messageпеременную и вывести ее на страницу.
Теперь давайте создадим родительский компонент для нашего MessageView. Создайте новый файл
import React, { Component } from ‘react’;
import MessageView from '. /
class MessageList extends Component {
state = {
message: {
from: ‘Martha’,
content: ‘I will be traveling soon’,
status: ‘read’
}
}
render () {
return (
List of Messages
)
}
}
export default MessageList;
Здесь мы используем состояние для хранения объекта, содержащего наше сообщение. Часть магии React заключается в том, что при изменении объекта состояния компонент будет повторно отображаться (таким образом, обновляя пользовательский интерфейс).
Затем в нашем JSX мы передаем messageсвойство нашего stateобъекта MessageViewкомпоненту.
Последний шаг — обновить наш Appкомпонент, чтобы отобразить наш новый MessageListкомпонент с состоянием, в отличие от MessageViewкомпонента без состояния:
import React, { Component } from ‘react’;
import MessageList from '. /
import '. /App.css’;
class App extends Component {
render () {
return (
)
}
}
export default App;
После сохранения изменений проверьте свой браузер, чтобы увидеть результат.
Список сообщений
Найдите минутку, чтобы убедиться, что вы понимаете, что происходит. Мы объявляем stateобъект в нашем MessageListкомпоненте (с сохранением состояния). Свойство messageэтого объекта содержит наше сообщение. В нашей renderфункции мы можем передать это сообщение нашему (без сохранения состояния) дочернему компоненту, используя то, что называется реквизитом.
В MessageViewкомпоненте (без сохранения состояния) мы можем получить доступ к сообщению, используя this.props.message. Затем мы можем передать это значение нашему JSX для отображения на странице.
Фу!
Проверка реквизита
По мере роста вашего приложения и передачи данных туда и обратно в качестве реквизита будет полезно проверить, что компоненты получают тип данных, который они ожидают.
К счастью, мы можем сделать это с помощью пакета
import React from ‘react’;
import PropTypes from ‘
class MessageView extends Component {
// This stays the same
]
MessageView.propTypes = {
message: PropTypes.object.isRequired
}
export default MessageView;
Это заставит ваше приложение React жаловаться, если messageопора отсутствует. Это также заставит его жаловаться, если компонент получит
Вы можете попробовать это, изменив состояние родительского компонента следующим образом:
state = {
message: ‘Not an object!'
}
Вернитесь в браузер и откройте консоль. Вы должны увидеть следующее, зарегистрированное в консоли:
Warning: Failed prop type: Invalid prop `message` of type `string` supplied to `MessageView`, expected `object`.
in MessageView (at
in MessageList (at App.js:9)
in App (at src/index.js:6)
Повторное использование компонентов
Теперь давайте посмотрим, как мы можем отображать несколько сообщений с помощью MessageViewэкземпляров. Именно здесь React начинает сиять, поскольку он невероятно упрощает повторное использование кода (как вы увидите).
Сначала мы перейдем state.messageк массиву и переименуем его в messages. Затем мы будем использовать функцию карты JavaScript для создания нескольких экземпляров MessageViewкомпонента, каждый из которых соответствует сообщению в state.messagesмассиве.
Нам также потребуется заполнить специальный атрибут с именем key уникальным значением, например id. React нуждается в этом, чтобы отслеживать, какие элементы в списке были изменены, добавлены или удалены.
Обновите MessageListкод следующим образом:
class MessageList extends Component {
state = {
messages: [
{
_id: ‘d2504a54',
from: ‘John’,
content: ‘The event will start next week’,
status: ‘unread’
},
{
_id: ‘fc7cad74',
from: ‘Martha’,
content: ‘I will be traveling soon’,
status: ‘read’
},
{
_id: '876ae642',
from: ‘Jacob’,
content: ‘Talk later. Have a great day!',
status: ‘read’
}
]
}
render () {
const messageViews = this.state.messages.map (
message =>
)
return (
List of Messages
{messageViews}
)
}
}
Проверьте свой браузер, чтобы увидеть результаты:
Цикл сообщений
Как видите, с помощью React легко определить стандартные блоки для создания мощных и сложных интерфейсов пользовательского интерфейса.
Рефакторинг для использования React Hooks
Хуки — это недавняя версия React, но они штурмом берут мир React. Проще говоря, они позволяют взять функциональный компонент React и добавить к нему состояние (и другие функции).
Я собираюсь закончить этот урок рефакторингом нашего MessageViewкомпонента, чтобы сделать его функциональным компонентом, который управляет своим состоянием с помощью хуков React. Обратите внимание, что это возможно только при использовании React v16.8 и выше.
import React, { useState } from ‘react’;
import MessageView from '. /
export default function MessageList () {
const initialValues = [
{
_id: ‘d2504a54',
from: ‘John’,
content: ‘The event will start next week’,
status: ‘unread’
},
{
_id: ‘fc7cad74',
from: ‘Martha’,
content: ‘I will be traveling soon’,
status: ‘read’
},
{
_id: '876ae642',
from: ‘Jacob’,
content: ‘Talk later. Have a great day!',
status: ‘read’
}
];
const [messages] = useState (initialValues) ;
const messageViews = messages.map (
message =>
) ;
return (
List of Messages
{messageViews}
) ;
}
В приведенном выше примере я заменил stateобъект хуком useState React. Как следует из названия, это позволяет вам управлять состоянием компонента.
Использование хуков поможет вам избежать так называемого сверления опоры при работе над большими проектами. Детализация реквизита показывает, что вы пропускаете реквизит через несколько компонентов (которые в конечном итоге не нуждаются в этих данных) только для того, чтобы добраться до глубоко вложенного компонента.
Мы также можем преобразовать наш MessageViewкомпонент в функциональный компонент:
import React from ‘react’;
import PropTypes from ‘
const MessageView = ({ message }) => {
const { from, status, content } = message;
return (
From:
{from}
Status:
{status}
Message:
{content}
) ;
};
MessageView.propTypes = {
message: PropTypes.object.isRequired
}
export default MessageView;
Обратите внимание, как теперь мы получаем свойство сообщения в нашем компоненте:
const MessageView = ({ message }) => {
...
}
При этом используется метод, называемый деструктурированием объектов, который позволяет извлекать отдельные элементы из массивов или объектов и помещать их в переменные с использованием сокращенного синтаксиса.
Здесь мы используем ту же технику, чтобы получить нужные нам значения из messageобъекта и избежать добавления ко всему префикса message:
const { from, status, content } = message;
И это много!
Я не хочу дальше в этой статье вдаваться в подробности об хуках React, а просто хочу, чтобы вы знали, что они существуют и становятся все более популярными среди сообщества React. Если вы хотите узнать больше о хуках, прочтите наше руководство по началу работы с React Hooks.
Демо
Вот живая демонстрация, с которой вы можете поиграть:
Куда пойти отсюда
Мы подошли к концу этого вводного руководства. Есть еще множество концепций React, которые я не смог охватить, например выборка данных, обработка ошибок, маршрутизация, работа с формами, отладка. Список можно продолжить...