Урок 26 из 49 · Месяц 4. React
Знакомство с React, установка и JSX
Содержание урока
- Что такое React
- Зачем React, если есть обычный JavaScript
- Как React обновляет страницу
- Установка React через Vite
- Шаг 1. Проверяем Node.js
- Шаг 2. Создаём проект
- Шаг 3. Смотрим структуру проекта
- Как React попадает на страницу
- Что такое JSX
- Правила JSX
- Фигурные скобки: JavaScript внутри разметки
- Условный рендеринг
- Рендеринг компонентов
- Первый компонент
- Что происходит при рендеринге
- Типичные ошибки новичков
- Практика
- Итоги
В этом уроке мы познакомимся с React — самой популярной библиотекой для создания интерфейсов. Разберёмся, зачем она нужна, создадим первый проект через Vite, поймём, что такое JSX, и выведем на страницу свои первые компоненты. Всё, что вы выучили про JavaScript за прошлые месяцы, здесь пригодится каждый день.
Что такое React
React — это JavaScript-библиотека для создания пользовательских интерфейсов (UI): кнопок, списков, форм, целых страниц. Её создали в Facebook (сейчас Meta), и сегодня на React написаны тысячи сайтов и приложений.
Главная идея React — интерфейс собирается из компонентов. Компонент — это кусочек интерфейса со своей разметкой и логикой: шапка сайта, карточка товара, кнопка «Купить».
Аналогия: конструктор LEGO. Вы один раз делаете деталь «карточка товара», а потом используете её сколько угодно раз — на главной странице, в каталоге, в корзине. Если поменять деталь, она поменяется везде.
<App>
├── <Header>
│ └── <Menu>
├── <ProductList>
│ ├── <ProductCard>
│ ├── <ProductCard>
│ └── <ProductCard>
└── <Footer>
Зачем React, если есть обычный JavaScript
В уроке Введение в DOM мы меняли страницу вручную: находили элемент, создавали новый, добавляли класс. Для маленькой страницы это нормально. Но представьте интернет-магазин: корзина, фильтры, счётчик товаров в шапке, уведомления. Изменилось одно число — и нужно не забыть обновить его в пяти местах.
Сравним. Обычный JavaScript — императивный подход: вы командуете браузеру каждый шаг.
const button = document.querySelector('#btn');
const counter = document.querySelector('#counter');
let count = 0;
button.addEventListener('click', () => {
count++;
counter.textContent = count; // сами вручную обновляем DOM
});
React — декларативный подход: вы описываете, как должен выглядеть интерфейс при текущих данных, а React сам решает, что изменить в DOM.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Нажато: {count}</button>;
}
Пока не пугайтесь useState — это тема отдельного урока. Важно увидеть идею: мы не трогаем DOM руками. Мы меняем данные, а React обновляет страницу.
Как React обновляет страницу
Работа с настоящим DOM — относительно медленная операция. Поэтому React держит в памяти лёгкую копию интерфейса (её часто называют виртуальным DOM). Когда данные меняются, React:
- строит новую версию интерфейса в памяти;
- сравнивает её со старой;
- меняет в настоящем DOM только то, что действительно изменилось.
Это как редактор, который не перепечатывает всю книгу из-за одной опечатки, а исправляет только нужную букву.
Установка React через Vite
Раньше проекты создавали через Create React App, но он устарел и больше не рекомендуется. Сегодня стандарт — Vite (читается «вит», от французского «быстро»). Это инструмент сборки: он запускает dev-сервер, мгновенно обновляет страницу при сохранении файла и собирает проект для публикации.
Шаг 1. Проверяем Node.js
Vite работает на Node.js. Откройте терминал и проверьте версии (про npm мы говорили в уроке npm и package.json):
node -v
npm -v
Если команда не найдена — установите LTS-версию Node.js с официального сайта nodejs.org. Новым версиям Vite нужен свежий Node.js (20+ или новее), поэтому старый Node лучше обновить.
Шаг 2. Создаём проект
npm create vite@latest my-react-app -- --template react
npm create vite@latest— запускает свежую версию генератора проектов Vite;my-react-app— название папки проекта;-- --template react— шаблон «React + JavaScript». Для TypeScript есть шаблонreact-ts, к нему вернёмся в уроке TypeScript.
Генератор может задать пару вопросов (например, «установить зависимости и запустить сейчас?»). Можно согласиться — или выполнить шаги вручную:
cd my-react-app
npm install
npm run dev
В терминале появится адрес вроде http://localhost:5173/. Откройте его в браузере — вы увидите стартовую страницу Vite + React со счётчиком.
Шаг 3. Смотрим структуру проекта
my-react-app/
├── node_modules/ ← установленные библиотеки (не трогаем, не коммитим)
├── public/ ← файлы «как есть» (favicon и т. п.)
├── src/ ← ваш код живёт здесь
│ ├── assets/ ← картинки, импортируемые из кода
│ ├── App.css
│ ├── App.jsx ← главный компонент
│ ├── index.css ← глобальные стили
│ └── main.jsx ← точка входа
├── index.html ← единственная HTML-страница
├── package.json ← зависимости и скрипты
└── vite.config.js ← настройки Vite
Скрипты в package.json:
| Команда | Что делает |
|---|---|
npm run dev |
Запускает dev-сервер для разработки |
npm run build |
Собирает готовый сайт в папку dist |
npm run preview |
Показывает собранную версию локально |
Как React попадает на страницу
Откройте index.html. Внутри почти пусто:
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
Пустой div с id="root" — это «контейнер», в который React нарисует всё приложение. Теперь src/main.jsx:
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App.jsx';
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
);
Разберём по строчкам:
import { StrictMode } from 'react'— берём из React специальный компонент-«строгий проверяющий». В режиме разработки он помогает находить ошибки (и иногда специально вызывает код дважды — это нормально).import { createRoot } from 'react-dom/client'—react-domсвязывает React с браузерным DOM.import './index.css'— подключаем глобальные стили. Да, в проектах на Vite CSS можно импортировать прямо в JS.import App from './App.jsx'— импортируем главный компонент.createRoot(...)— создаём «корень» React внутриdiv#root..render(<App />)— говорим: «нарисуй здесь компонент App».
Получается цепочка: index.html → main.jsx → App.jsx → остальные компоненты.
Что такое JSX
Посмотрите на эту строку:
const title = <h1 className="title">Привет, React!</h1>;
Это не строка и не HTML. Это JSX — расширение синтаксиса JavaScript, которое позволяет писать разметку прямо в коде. Браузер JSX не понимает, поэтому Vite перед запуском превращает его в обычный JavaScript. Примерно так:
const title = React.createElement('h1', { className: 'title' }, 'Привет, React!');
Писать createElement вручную неудобно, поэтому все используют JSX. Файлы с JSX обычно называют с расширением .jsx.
Правила JSX
JSX похож на HTML, но у него есть строгие правила. Это частый источник ошибок у новичков.
1. Компонент возвращает один корневой элемент. Нельзя вернуть два соседних тега:
// ❌ Ошибка: два элемента рядом
return (
<h1>Заголовок</h1>
<p>Текст</p>
);
Оберните их в div или во фрагмент <>... — пустую обёртку, которая не попадает в DOM:
// ✅ Правильно
return (
<>
<h1>Заголовок</h1>
<p>Текст</p>
</>
);
2. Все теги закрываются. Даже те, что в HTML можно не закрывать:
<img src="/logo.svg" alt="Логотип" />
<input type="text" />
<br />
3. className вместо class. Слово class в JavaScript занято (классы ООП), поэтому:
<div className="card">Карточка</div>
<label htmlFor="email">Email</label> {/* for → htmlFor */}
4. Атрибуты в camelCase. onclick → onClick, tabindex → tabIndex, maxlength → maxLength. Исключение — data-* и aria-*, они пишутся как в HTML.
5. style — это объект, а не строка. Свойства тоже в camelCase:
<p style={{ color: 'red', fontSize: '20px', marginTop: 10 }}>Важный текст</p>
Двойные фигурные скобки — это не особый синтаксис: внешние {} означают «здесь JavaScript», внутренние — обычный объект. Число 10 React сам превратит в 10px.
6. Комментарии пишутся внутри фигурных скобок: {/* комментарий */}.
Фигурные скобки: JavaScript внутри разметки
Внутри {} можно писать любое выражение JavaScript — то, что возвращает значение: переменную, вычисление, вызов функции, тернарный оператор.
function Profile() {
const name = 'Айгерим';
const age = 21;
const avatar = 'https://example.com/avatar.png';
function getGreeting() {
const hour = new Date().getHours();
return hour < 12 ? 'Доброе утро' : 'Добрый день';
}
return (
<div className="profile">
<img src={avatar} alt={name} width={80} />
<h2>{getGreeting()}, {name}!</h2>
<p>Через год вам будет {age + 1}</p>
<p>Имя в верхнем регистре: {name.toUpperCase()}</p>
</div>
);
}
Разбор:
src={avatar}— значение атрибута берётся из переменной (без кавычек!). Кавычки — для обычных строк:alt="Фото".{getGreeting()}— вызываем функцию, её результат появится в тексте.{age + 1}— любое вычисление.width={80}— число передаём в фигурных скобках.
Условный рендеринг
Часто нужно показать элемент только при каком-то условии.
function Greeting() {
const isLoggedIn = true;
const unread = 3;
// Способ 1: if до return
if (!isLoggedIn) {
return <p>Пожалуйста, войдите в аккаунт</p>;
}
return (
<div>
{/* Способ 2: тернарный оператор — «или то, или другое» */}
<h1>{isLoggedIn ? 'С возвращением!' : 'Здравствуйте, гость'}</h1>
{/* Способ 3: && — «показать, только если true» */}
{unread > 0 && <p>У вас {unread} новых сообщения</p>}
</div>
);
}
Как работает &&: если левая часть ложна, React ничего не рисует; если истинна — рисует то, что справа.
Что React выводит, а что нет: строки и числа — показывает; null, undefined, true, false — ничего не показывает. Обычный объект {} вывести нельзя — будет ошибка «Objects are not valid as a React child».
Рендеринг компонентов
Первый компонент
Компонент в React — это обычная функция, которая возвращает JSX. Два правила:
- Имя начинается с большой буквы:
Header, а неheader. По этому признаку React отличает ваши компоненты от HTML-тегов. - Функция возвращает разметку (или
null, если показывать нечего).
Откройте src/App.jsx, удалите всё и напишите:
function Header() {
return (
<header>
<h1>Мой первый сайт на React</h1>
</header>
);
}
function Footer() {
const year = new Date().getFullYear();
return <footer>© {year} Все права защищены</footer>;
}
function App() {
return (
<div>
<Header />
<main>
<p>Здесь будет контент.</p>
</main>
<Footer />
</div>
);
}
export default App;
Сохраните файл — страница в браузере обновится сама. Это HMR (горячая перезагрузка) от Vite.
Разбор:
HeaderиFooter— маленькие компоненты, каждый отвечает за свой кусок страницы.<Header />— так компонент используется (рендерится). Это как свой собственный HTML-тег.App— главный компонент, который собирает остальные. Его мы импортировали вmain.jsx.export default App— экспорт, чтобыmain.jsxмог его импортировать. Подробно про импорт и экспорт — в уроке Компоненты и пропсы.- Круглые скобки после
returnнужны, когда JSX занимает несколько строк. Без них JavaScript может решить, чтоreturnпустой.
Что происходит при рендеринге
Рендеринг — это когда React вызывает вашу функцию-компонент, получает JSX и показывает результат на странице. Порядок такой:
createRoot(...).render(<App />)— React вызывает функциюApp.- Внутри
Appесть<Header />— React вызываетHeader, и так вниз по дереву. - Из всех результатов React строит DOM и вставляет его в
#root. - Когда данные изменятся, React снова вызовет нужные функции и обновит только изменённые части.
Поэтому компонент должен быть чистой функцией: при одинаковых данных возвращать одинаковый результат и не менять ничего снаружи во время рендера.
Типичные ошибки новичков
| Ошибка | Как выглядит | Как исправить |
|---|---|---|
| Имя компонента с маленькой буквы | function header() и <header /> |
function Header() и <Header /> |
class вместо className |
<div class="box"> |
<div className="box"> |
| Незакрытый тег | <img src="a.png"> |
<img src="a.png" /> |
| Два корневых элемента | return <h1/><p/> |
Обернуть во фрагмент <>... |
style строкой |
style="color: red" |
style={{ color: 'red' }} |
| Вызов функции-компонента | {Header()} |
<Header /> |
if внутри JSX |
{if (ok) ...} |
Тернарник или && |
Практика
- Новый проект. Создайте проект
react-startчерез Vite, запуститеnpm run dev, очиститеApp.jsxи выведите заголовок «Привет, React!». Ожидаемый результат: наlocalhost:5173только ваш заголовок. - Визитка. Создайте компонент
BusinessCard, который показывает имя, профессию, город и фото (черезsrc={...}из переменной). Стили задайте черезstyle={{ ... }}. Ожидаемый результат: карточка с данными из переменных, а не вписанными в разметку. - Сборка страницы. Сделайте компоненты
Header,Main,Footerи соберите их вApp. ВFooterвыведите текущий год черезnew Date().getFullYear(). Ожидаемый результат: три части страницы, каждая — отдельный компонент. - Условия. Создайте переменные
isOnline(true/false) иmessages(число). Если пользователь онлайн, покажите зелёную надпись «В сети», иначе серую «Не в сети». Блок «Новых сообщений: N» показывайте только еслиmessages > 0. Проверьте, что приmessages = 0на странице не появляется ноль. - Время суток. Компонент
DayGreetingпоказывает «Доброе утро» / «Добрый день» / «Добрый вечер» / «Доброй ночи» в зависимости от текущего часа. Логику вынесите в функцию доreturn. Ожидаемый результат: правильное приветствие при перезагрузке страницы.
Итоги
- React — библиотека для интерфейсов, где страница собирается из компонентов, как из деталей LEGO.
- Новый проект создаётся командой
npm create vite@latest имя -- --template react, запускается черезnpm run dev. - Цепочка запуска:
index.html(div#root) →main.jsx(createRoot().render()) →App.jsx. - JSX — разметка внутри JavaScript: один корневой элемент, закрытые теги,
className,style={{}}, camelCase. - В
{}пишутся выражения; для условий — тернарник? :и&&(осторожно с нулём). - Компонент — функция с большой буквы, возвращающая JSX; используется как тег
<Header />.