Супербыстрое погружение в React
June 16, 2020
Реакт — самая популярная на данный момент библиотека для создания интерактивного интерфейса в браузере, современный веб просто невозможен без неё (ну ладно, возможен, большая веб-тройка — это react, angular и vue). Её создали в недрах фейсбука и выпустили в мир в 2013. В рамках статьи невозможно описать абсолютно все аспекты разработки на этой библиотеки, но можно показать основные концепты и написать первое мини-приложение. Приступим.
Установка
При знакомстве с реактом лучше всего начать с самой простой из всех возможных установок, а именно, просто подключить сам React
и ReactDom
к обычной html-страничке с какого-нибудь cdn. Для этого создадим index.html
:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Супербыстрое погружение в React</title>
<!-- подключаем React и ReactDOM -->
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
<!-- -->
<!-- подключаем Babel -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<!-- -->
</head>
<body>
<div id="root"></div>
<script type="text/babel">
<!-- дальнейший код пишем здесь -->
</script>
</body>
</html>
Кроме подключения двух главных реактовских библиотек, мы также подключили Babel. Так как реакт использует что-то называемое JSX для разметки (чуть позже посмотрим), Babel нам нужен для преобразования JSX в обычный JavaScript, который понятен браузеру.
Я хочу обратить внимание ещё на две штуки:
- div с
id="root"
, входная точка для приложения, внутри этого тега будет отображаться реакт-приложение. - тег
<script type="text/babel">
в<body />
. Я уже упоминал, что реакт использует JSX, который браузер не понимает, аттрибут type с неизвестным браузеру значением, заставляет его игнорировать содержимое этого тега, позволяя babel по-своему его обработать, и только потом подсунуть браузеру. Внутри этого тега мы будем писать весь код.
Компоненты
Как всё в JavaScript — объект, так всё в React — компонент. Это основные строительные блоки react-приложения. Обычно компоненты представляют собой JavaScript-классы. Чтобы создать компонент, нужно создать класс, отнаследовав его от класса React.Component
. по традиции, начнём с создания класса HelloWorld
.
class HelloWorld extends React.Component {
render() {
return <h1>Hello, World!</h1>
}
}
Главным методом класса-компонента является метод render
. то, что вернёт этот метод, реакт потом отрисует на веб-странице. В примере мы возвращаем заголовок <h1 />
c текстом “Hello World”.
Чтобы заставить наш хелло-ворлд работать, осталось только подсказать реакту, где отрисовать компонент на странице. Добавим в код:
ReactDOM.render(<HelloWorld />, document.getElementById('root'))
Мы говорим реакту отрисовать компонент на странице внутри тега с id=root
. Готово, теперь можно открыть index.html
в браузере — всё должно работать.
Код похожий на html (<h1 />
, <HelloWorld />
) — это упоминавшийся раньше JSX. Это синтаксический сахар, чтобы писать приложения можно было удобнее, под капотом Babel преобразует этот синтаксис в обычные JavaScript объекты. Это, может быть, не очень очевидно, но это весьма мощный инструмент. Для простоты картины можно считать, что реакт возьмёт эти html-теги и как есть вставит на страницу.
Обработка данных
В реакте два типа данных: пропсы (props, сокращение от properties, свойства) и стейт (состояние, state). Разницу между ними поначалу понять, так что не парьтесь, если что-то непонятно. Это станет очевидно, как только вы начнёте вплотную работать на реакте.
Ключевая разница в том, что стейт приватен и может быть изменён только изнутри самого́ компонента, а пропсы не контролируются самим компонентом, они передаются ему снаружи от родительского компонента и он должен на них как-то реагировать.
Компонент напрямую может изменять свой стейт. Компонент не может менять свои пропсы.
Пропсы
Компонент <HelloWorld />
полностью статичен, возвращает одну и туже строку независимо ни от чего. Это не совсем то, чего нам хотелось — реакт как раз создан для динамичных веб-приложений, а также с идеей переиспользования компонентов: написал раз — используй повсюду. К примеру, можно добавить немножко динамики, научив его отображать разные сообщения.
Чтобы добиться этого, воспользуемся пропсами — передадим через них имя того, кого хотим поприветствовать. Передавать пропсы просто, это выглядит как просто добавление атрибутов к html-тегу (помним, что это не html!)
ReactDOM.render(<HelloWorld name='wcademy' />, document.getElementById('root'))
Мы передаём свойство name со значением React. Получить пропсы изнутри компонента можно обратившись к this.props
:
class HelloWorld extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>
}
}
В результате на экране появится:
Обратите внимание на фигурные скобки вокруг this.props.name, этот синтаксис говорит, что это не просто строка, которую надо вывести (попробуйте без них), а JavaScript, который необходимо выполнить и подставить уже результат выполнения.
Уже неплохо, у нас есть реюзабельный компонент, который может поздороваться с кем угодно. А что если мы хотим, чтобы компонент имел какое-то состояние и мог менять его изнутри? Перейдём к стейту.
Стейт
Другой источник данных для компонента — его собственный стейт. И, в отличие от пропсов, которые компонент никак не может поменять, стейт формируется и хранится внутри.
Так что, если нужно изменить какие-то данные внутри компонента, например, из-за действий пользователя, эти данные стоит хранить в стейте.
Инициализация стейта.
Чтобы добавить в компонент дефолтное состояние, просто определим у класса новое поле state, как объект, содержащий интересующие нас ключи. В нашем случае — message.
class HelloWorld extends React.Component {
state = {
message: 'hello',
}
render() {
return (
<h1>
{this.state.message}, {this.props.name}!
</h1>
)
}
}
Изменение стейта
Для того чтобы изменить стейт в родительском классе Component, есть специальный метод setState. В качестве аргумента он принимает функцию, которая должна вернуть компоненту его новое состояние.
class HelloWorld extends React.Component {
state = {
message: 'hello',
}
updateState = () => {
this.setState(state => {
return {
message: state.message === 'hello' ? 'bye' : 'hello',
}
})
}
render() {
return (
<h1>
{this.state.message}, {this.props.name}!
</h1>
)
}
}
Мы добавили функцию, которая при вызове меняет стейт, изменяя сообщение “hello” на “bye”, и обратно.
Обработка событий
Следующим шагом, мы добавим кнопку, клик по которой будет вызывать updateState
и менять отображаемое сообщение.
class HelloWorld extends React.Component {
state = {
message: 'hello',
}
updateState = () => {
this.setState(state => {
return {
message: state.message === 'hello' ? 'bye' : 'hello',
}
})
}
render() {
return (
<div>
<h1>
{this.state.message}, {this.props.name}!
</h1>
<button onClick={this.updateState}>Клик-клик-клик</button>
</div>
)
}
}
Мы навесили обработку события клика на кнопку, как только пользователь кликнет по ней, стейт изменится на новый.
Поздравляю! Всего за несколько минут мы познакомились с основными концептами реакта и написали первый (а может для кого-то и не первый?) компонент реакта. Полный код можно найти на гитхабе.