Курс ведётся на русском языке: видео и материалы русскоязычные. Украинская версия курса появится позже.
Что вы сможете после курса
- Создавать классовые и функциональные компоненты и осознанно выбирать подход под задачу
- Управлять состоянием приложения через setState, useState, useReducer и контекст
- Собирать формы любого состава: текстовые поля, чекбоксы, радиокнопки, списки, валидация и рефы
- Получать данные из публичных API и обрабатывать неудачные запросы
- Строить навигацию одностраничного приложения: маршруты, вложенные страницы, хуки роутера
- Доводить проект до публикации: сборка, хранение ключей, выкладка на GitHub Pages
Кому подойдёт курс
Начинающим с нуля
Курс начинается с установки Node.js, редактора и первых понятий, а первый компонент собирается ещё без сборки. Каждый шаг разбирается до мелочей, а самостоятельные задания с разбором закрепляют материал.
Знающим JavaScript
Если вы уже пишете на JavaScript, курс сразу даст практику: createElement, JSX, компоненты, состояние и настоящие API. Вместо сухой теории — три проекта в портфолио.
Вернувшимся в разработку
Если вы сталкивались с классовыми компонентами и хотите догнать современный стек, половина курса про это: хуки, контекст, редюсеры и роутинг в актуальном стиле.
Курс не подойдёт, если нужен бэкенд, TypeScript или Redux: код пишется на JavaScript, данные берутся из готовых публичных API, а состояние — на встроенных средствах React
Как проходит обучение
- От простого к сложному: от первого компонента до магазина — Каждый новый приём опирается на предыдущий, и код не превращается в набор непонятных строк
- Три проекта, доведённых до публикации — Кроме навыков остаётся портфолио: поиск фильмов, интернет-магазин и SPA с рецептами
- Самостоятельное задание, затем разбор решения — Сначала пробуете сами, потом видите рабочий код и понимаете, где ошиблись
- Одни задачи в двух стилях: классовые компоненты и хуки — Видно, как устроен React под капотом, и свободно читаются оба стиля кода
- Работа с настоящими API: фильмы и рецепты — Учитесь на реальных запросах и ответах, а не на выдуманных примерах
Что понадобится
- Компьютер с Windows, macOS или Linux
- Платформа Node.js и редактор Visual Studio Code — установка показана в курсе
- Бесплатный ключ к API фильмов — как получить, разобрано в уроках
Почему самому обычно не выходит
React кажется простым, пока не открываешь документацию: десятки хуков, сборщики, конфиги, версии. Без системы легко застрять на этапе, когда npm не работает, и бросить. Случайные статьи и видео дают куски знаний, которые не складываются в целое: отдельный компонент написать получается, а приложение — нет.
Курс выстраивает путь: от чистого React без сборки до полноценного одностраничного приложения. На каждом шаге вы пишете код руками, самостоятельные задания с разбором показывают ошибки, а три проекта дают опыт, который переносится в работу.
Что изменится
До курса
- React — набор непонятных слов: JSX, props, виртуальный DOM
- Интерфейс собирается одной большой HTML-простыней
- Состояние приложения хранится где попало
- Данные для страницы копируются руками
- Готовый проект непонятно куда девать
После курса
- Понимаете, как React устроен изнутри, и объясняете его своими словами
- Разбиваете интерфейс на компоненты и переиспользуете их
- Держите состояние под контролем: useState, useReducer и контекст
- Получаете данные из API и обрабатываете ошибки загрузки
- Публикуете приложения на GitHub Pages и показываете их работодателю
Как устроен путь
- Настройка и первые компоненты Ставите инструменты, пробуете React без сборки, пишете первый компонент и переводите его на JSX
- Ядро библиотеки Классовые компоненты, состояние, жизненный цикл, формы и работа со списками — на коротких упражнениях
- Проекты Собираете поиск фильмов и интернет-магазин с корзиной, подключая настоящие API
- Современный React Переходите на хуки, контекст и редюсеры, добавляете роутинг и публикуете SPA
Программа курса
88 уроков · 11 модулей · 11 часов 50 минут видео · Каждый раздел заканчивается практикой: самостоятельное задание и разбор его решения.
-
Обзор курса и трёх учебных проектов, знакомство с React и его отличиями от классической разработки, проверка знаний, установка Node.js, редактора и React DevTools, выбор окружения — песочница CodeSandbox, Create React App или сборщик Parcel.
- Что такое React и его преимущества над классической разработкой7:06
Разбираемся, что такое React — компактная библиотека на JavaScript для построения пользовательских интерфейсов — и чем она отличается от коробочных фреймворков вроде Angular и Vue. Смотрим, почему разметка создаётся из кода, а не загружается готовой с сервера, и как виртуальный DOM вместе с декларативным подходом избавляют от ручного обновления страницы. Отдельно говорится о сборке интерфейса из компонентов, которые можно переиспользовать.
- Пререквизит знаний и где добирать при наличии пробелов2:49
Определяем минимальный набор знаний для старта: основы HTML для форм и базовых элементов страницы, классы и идентификаторы в CSS, а также базовый JavaScript — функции, переменные, массивы, объекты. Тем, у кого есть пробелы, предлагается плейлист про фундаментальный JavaScript со стрелочными функциями, деструктуризацией, методами массивов и промисами. Отдельно объясняется, что Node.js и Git не требуют глубокой предварительной подготовки.
- Что необходимо установить3:03
Пошагово готовим окружение: устанавливаем LTS-версию Node.js, редактор кода Visual Studio Code и браузерное расширение React DevTools. Проверяем установку командами node -v и npm -v в терминале, находим расширение в магазине Chrome, закрепляем его значок и узнаём, какие вкладки оно добавляет в панель разработчика. Результат — окружение, готовое к первым запускам проектов.
- Варианты окружения9:38
Разбираем три способа подготовить окружение: онлайн-песочница CodeSandbox, локальный проект через Create React App и ручная сборка с бандлером Parcel. Показываем, как в песочнице подключать дополнительные пакеты и где писать код приложения, а также как командой npx развернуть стартовый шаблон и запустить его локальным веб-сервером. Для первого знакомства предлагается начать с работы прямо в браузере.
- Что такое React и его преимущества над классической разработкой7:06
-
Подключаете React и ReactDOM к обычной HTML-странице, собираете приложение на createElement, переводите его на JSX, делите код на модули и добавляете условную отрисовку с прелоадером.
- Библиотеки React и ReactDOM8:52
Знакомство с React без шаблонизаторов: библиотеки React и ReactDOM подключаются к обычной HTML-странице по CDN-ссылкам. Создаётся корневая нода — контейнер будущего приложения, первый компонент собирается через React.createElement и выводится на страницу методом render. Разбирается, зачем нужна каждая из двух библиотек и как задавать элементам атрибуты.
- Простое приложение на чистом React8:35
Чистый React наращивается до небольшого приложения: компоненты вкладываются друг в друга и переиспользуются с разными данными. Значения передаются при вызове компонента и приходят в него через объект props, содержимое которого проверяется в консоли. Громоздкость вложенных вызовов createElement показывает, зачем дальше нужен JSX.
- Преобразование приложения в JSX7:03
Приложение переводится с createElement на JSX в онлайн-песочнице: библиотеки подключаются импортами из установленных пакетов вместо CDN-ссылок. Компоненты вызываются угловыми скобками, а данные передаются атрибутами. Отдельно разбираются обязательный закрывающий слэш у непарных тегов и имена собственных компонентов с большой буквы.
- Разбор задания по преобразованию компонента в JSX2:06
Разбор решения практического задания: компонент книги переписан с createElement на компактную запись на JSX. Ключевой момент — подстановка значений props внутрь разметки фигурными скобками, иначе там печатается текст вроде props.name вместо реального значения. Заодно обсуждается, что неясные вводные и самостоятельный поиск информации — обычная часть работы веб-разработчика.
- Особенности JSX10:21
Систематизация правил JSX: это шаблонизатор, который собирает разметку из данных и опирается на возможности JavaScript. В фигурные скобки разрешено помещать только выражения — вызовы функций, тернарные операторы, но не инструкции вроде if или циклов. Разбираются замена class на className, комментарии, закрытие одиночных тегов слэшем, название компонентов с большой буквы и попадание вложенного содержимого в props.children.
- Разделение приложения на модули5:50
Проект делится на модули: компонент книги и корневой App переносятся в отдельные файлы и подключаются через export и import. Разбираются отличия export default от именованного экспорта и причина ошибки React is not defined, которую лечит импорт React. Код, разнесённый по файлам, проще поддерживать — дальше каждый компонент будет жить в собственном файле.
- Условная отрисовка3:21
Как компонент React показывает разную разметку в зависимости от условия или не рисует ничего. Два сложившихся подхода: тернарный оператор внутри return и обычный if в теле компонента с возвратом null для пустого результата. Объясняется, почему пустой разметки даёт именно null и почему после первой подошедшей ветки остальные return не выполняются.
- Пример с прелоадером3:23
Практический пример условной отрисовки: пока приложение получает данные, пользователь видит заглушку-прелоадер вместо основного содержимого. Компонент прелоадера выносится в отдельный файл и оформляется стрелочной функцией, а переключением управляет проп с флагом загрузки. Пока флаг задаётся обычной константой, полноценное управление значением появится при знакомстве с состояниями.
- Библиотеки React и ReactDOM8:52
-
Разбираете устройство базового шаблона, пишете классовые компоненты с состоянием и методами, учитесь работать со списками и атрибутом key и разбираете однонаправленный поток данных.
-
Из чего состоит React-шаблон, что такое компонент, как хранится и обновляется состояние, как правильно писать методы — и как всё это складывается в практику с кликером.
- Разбор составляющих базового React-шаблона14:03
Разбирается устройство проекта, созданного через Create React App: конфигурационные файлы, папки public и src, скрипты разработки и сборки. Показано, как убрать из шаблона служебные и демонстрационные файлы и получить компактную основу для собственного кода.
- Понятие React-компонента9:16
Объясняется идея деления интерфейса на переиспользуемые части — на примерах разложения страниц из официальной документации React. Затем пишется первый классовый компонент: наследование от React.Component, метод render для возврата JSX и конструктор, принимающий пропсы.
- Состояние компонента и управление им11:36
На примере кликера разбирается состояние классового компонента: чтение из this.state и обновление только через setState. Показаны обработчики событий в разметке, иммутабельность стейта и особенность, из-за которой несколько подряд идущих вызовов setState читают одно прежнее значение, — здесь помогает prevState. Отдельно рассматривается просмотр и правка state компонента в React DevTools.
- Нюансы создания методов в классовых компонентах4:13
Разбираются три рабочих способа подключить обработчик в классовом компоненте: метод-стрелочная функция, привязка через bind в конструкторе и анонимная функция прямо в атрибуте события. Показывается, почему обычный метод класса теряет this и вызов setState падает с ошибкой.
- Разбор практики с кликером4:09
Доводится до ума счётчик из практики: появляется вторая кнопка, значение выводится элементом span, а обработчики разделяются на increment, decrement и reset. Разросшуюся разметку оформляют по строкам, а объект инлайн-стилей выносится в отдельную константу.
- Разбор составляющих базового React-шаблона14:03
-
Понятие жизненного цикла компонента, самостоятельное задание на таймер и разбор его решения: интервалы, сохранение в Local Storage и корректная зачистка.
- Понятие жизненного цикла React-компонента17:47
Знакомство с этапами жизни классового компонента: монтирование, обновление и размонтирование. Разбираются три основных метода — componentDidMount для разовых действий вроде загрузки данных, componentDidUpdate после каждого обновления и componentWillUnmount для очистки. В демо посты приходят с сервера, а запущенный интервал обязательно снимается при удалении компонента со страницы.
- Задание на создание таймера: что надо сделать1:03
Постановка практики: собрать таймер, где клик запускает интервал, периодически наращивающий число в состоянии компонента. Предусмотреть остановку, повторный запуск и сброс значения, а по желанию — сохранять его в local storage, чтобы счёт продолжался с прежнего места после перезагрузки страницы.
- Разбор практики по созданию таймера8:07
Разбор решения: пишутся методы старта, остановки и сброса на setInterval и clearInterval, обработчики оформлены стрелочными функциями ради сохранения контекста класса. Актуальный счётчик записывается в Local Storage при каждом обновлении и восстанавливается при монтировании, причём строку из хранилища нужно привести к числу; интервал отменяется при размонтировании.
- Понятие жизненного цикла React-компонента17:47
-
Вывод коллекций через map с атрибутом key, однонаправленный поток данных и обновление состояния из дочерних компонентов — с заданием и разбором, плюс отличие классовых компонентов от функциональных.
- Работа с коллекциями и атрибутом key4:59
Показывается вывод массива постов методом map внутри JSX вместо дублирования одинаковой разметки для каждой записи. Объясняется, зачем спискам собственный key: с ним React находит нужный узел и точечно обновляет страницу, а индекс массива в роли ключа не рекомендуется.
- Однонаправленный поток данных и состояния10:26
Разбирается однонаправленный поток данных: пропсы движутся лишь в одну сторону, от родительского компонента к дочерним. Чтобы потомок мог влиять на общий стейт, родитель спускает вниз функцию-колбэк, а деструктуризация значений стейта и пропсов в render делает код короче и читаемее.
- Задание на обновление состояния через дочерние компоненты0:42
Постановка практики: удалить из состояния конкретный пост нажатием кнопки Delete на его карточке. Функцию удаления предстоит объявить в корневом компоненте, передать вниз через список постов и подключить к кнопке — в итоге ненужная запись пропадает и из данных, и с экрана.
- Разбор практики по обновлению состояния через дочерние компоненты3:55
Разбор решения: в родительском классе создаётся метод удаления, который фильтрует массив постов по идентификатору и обновляет состояние через setState. Функция пробрасывается через пропсы в карточку, где вызывается анонимным обработчиком клика с id записи; отдельно разбираются типичные ошибки с контекстом и опечатками в коде.
- Отличие классовых компонентов от функциональных в классическом понимании1:24
Объясняется классическое правило выбора типа компонента: если нужны состояние или методы жизненного цикла, пишется класс, во всех остальных случаях достаточно функции. На его основе понятно, почему корневой компонент со стейтом сделан классовым, а простой список постов — функцией; упомянуто, что хуки позже сняли это ограничение.
- Работа с коллекциями и атрибутом key4:59
-
-
Управляемые компоненты и принцип единой ответственности, валидация полей, чекбоксы, радиокнопки, select и textarea, форма подписки с заданием и разбором, рефы с управлением фокусом и неуправляемые компоненты.
- Управляемые компоненты – принцип единой ответственности10:24
Практика по управляемым формам: значения полей живут в состоянии классового компонента, а ввод синхронизируется со state через onChange. Разбирается, почему поле без обработчика блокируется, и как один обработчик с динамическим ключом по атрибуту name обслуживает сразу несколько полей.
- Валидация значений формы7:14
Простая проверка формы при уходе из поля: имя оценивается по минимальной длине, email — по регулярному выражению. Сообщение об ошибке выводится через alert по событию onBlur, а работу регулярки отлаживают в консоли. Упоминается вынесение типовых проверок в отдельные helper-методы.
- Элементы checkbox, radio button, select, textarea8:40
Оставшиеся элементы формы переводятся под контроль React: textarea и select управляются через value, чекбоксы — через атрибут checked, а отмеченность радиокнопки вычисляется сравнением состояния со значением кнопки. Показывается, как задать чистый вариант select через отключённую пустую опцию и подписать элемент через label.
- Задание на создание формы подписки1:14
Самостоятельное задание по итогам темы: собрать форму подписки из поля email, чекбокса согласия и кнопки отправки. Нужно предусмотреть три сценария — предупреждение при неверном адресе, сообщение при неотмеченном согласии и очистку формы после успешной подписки.
- Решение практики по созданию формы подписки7:17
Разбор одного из вариантов решения задания о форме подписки: поле почты и чекбокс получают собственные обработчики изменения и записывают значения в состояние компонента. Клик по кнопке запускает проверку почты регулярным выражением и отметки согласия; при успехе форма очищается, а отправка на сервер лишь имитируется.
- Использование рефов и управление фокусом8:54
Знакомство с рефами — указателями на узлы страницы: создание через createRef и доступ к узлу через свойство current после монтирования. Отрабатываются два приёма с фокусом: курсор сам встаёт в поле при загрузке компонента, а после ввода полного номера карты автоматически переходит к полю почты.
- Неуправляемые компоненты4:58
Альтернатива управляемым формам: значения полей читаются из рефов в момент отправки, состояние и обработчики ввода не используются. Разбирается отмена стандартного поведения формы, проверки данных в обработчике отправки, очистка полей через рефы и отличие рефов от состояния — их обновление не вызывает повторный рендер.
- Управляемые компоненты – принцип единой ответственности10:24
-
С нуля собираете приложение поиска фильмов: каркас с шапкой и подвалом, запросы к API базы фильмов, список карточек, строка поиска, фильтр по категории, обработка неудачного поиска и безопасное хранение ключа, сборка и публикация.
- Обзор проекта «Фильмы». Постановка задачи2:01
Разбирается устройство будущего приложения — сервиса поиска фильмов и сериалов: экраны, поведение выдачи, прелоадер и фильтры по категориям. Показан каркас из шапки, подвала и рабочей области, где запрос меняет состояние, а состояние — отрисовку списка фильмов. Уточняется, какие темы предыдущих модулей закрепятся при сборке.
- Подготовка проекта, создание шапки и подвала16:03
Проект разворачивается из шаблона create-react-app: заготовка чистится от лишнего кода, подключается библиотека стилей Materialize CSS через CDN. Создаются функциональные компоненты шапки и подвала, атрибуты переносятся на className, а три области страницы объединяются React-фрагментом. Подвал прижимается к низу страницы при любом объёме контента.
- Знакомство с API базой фильмов6:54
Разбирается открытая база фильмов OMDB API: как оформить персональный ключ и какие ограничения у бесплатного тарифа. Показана структура запроса — поиск по названию, подробности по идентификатору, выбор формата ответа. Запросы пробуются в Postman, где изучается состав JSON-ответа с найденными фильмами.
- Задание на создание общего списка фильмов1:28
Самостоятельное задание: отправить к API запрос по готовой заготовке и сохранить в состояние массив найденных фильмов, а не весь объект ответа. Вывод разделяется между двумя компонентами — списком и карточкой одного фильма, для которой подбирается готовый вариант с изображением.
- Решение практики по созданию общего списка фильмов15:48
Карточка фильма и список оформляются отдельными компонентами, данные приходят через пропсы, а разметка карточки адаптируется под требования JSX. Главный компонент переводится в классовый со состоянием: запрос к API выполняется после монтирования, пока данных нет — на экране заглушка ожидания. Выдача выстраивается адаптивной сеткой, ключи для элементов берутся из идентификаторов, а фильмы без постера получают картинку-заглушку.
- Добавление строки поиска7:26
Временная надпись ожидания заменяется прелоадером из Materialize CSS, вынесенным в отдельный компонент. Строка поиска создаётся классовым компонентом: поле ввода делается управляемым, его значение хранится в состоянии и обновляется через setState. Обновление выдачи после нажатия Enter предлагается реализовать самостоятельно через функцию, переданную вниз через пропсы.
- Решение практики по реализации поиска фильмов4:48
Разбор самостоятельного задания: функция поиска создаётся в главном компоненте, адрес запроса собирается шаблонной строкой с подстановкой введённого текста, а массив фильмов в состоянии заменяется новыми данными. Через пропсы функция спускается в поле поиска и запускается клавишей Enter — для этого проверяется event.key. Рядом с вводом добавляется кнопка, размещённая внутри строки поиска.
- Задание на добавление фильтрации по категории1:09
Самостоятельное задание на доработку поиска: в интерфейсе появляется радиокнопка выбора категории — только фильмы или только сериалы. Выбор хранится в состоянии компонента и превращается в дополнительный параметр type в поисковом запросе, а при варианте «все» этот параметр в запрос не добавляется.
- Решение практики по добавлению фильтрации по категориям13:02
В компонент поиска добавляются три радиокнопки — все, фильмы, сериалы; флажок checked каждой кнопки вычисляется сравнением состояния фильтра с её значением из data-атрибута. Выбранная категория прикрепляется к запросу параметром type, после чего выдача показывает только фильмы или только сериалы. Дополнительно настраивается Prettier для единообразного форматирования кода.
- Обработка неудачного поиска4:03
Для прелоадера вводится отдельное булево состояние загрузки: он включается при старте запроса и выключается после получения данных, а не по пустому списку. Пустая выдача заменяется сообщением о том, что ничего не найдено. Разбирается и случай, когда вместо массива приходит undefined из-за ответа с ошибкой, — выручает значение по умолчанию.
- Безопасное хранение ключа API4:01
Ключ API переносится из кода в локальный файл переменных окружения, который не попадает в git: имя переменной задаётся с обязательным префиксом React-приложения, а значение читается через process.env и подставляется в оба запроса проекта. Отмечается, что полной защиты это не даёт — итоговый адрес запроса всё равно виден в инструментах разработчика.
- Сборка приложения и выгрузка на продакшн13:35
Приложение собирается командой build и публикуется на GitHub: создаётся репозиторий, локальная папка связывается с удалённой, секретные переменные переносятся в настройки репозитория. Пакет gh-pages устанавливается как dev-зависимость и выкладывает собранную статику на отдельную ветку. Отдельно устраняется ошибка смешанного контента переводом ссылки API на HTTPS и добавляется обработка ошибок запросов.
- Обзор проекта «Фильмы». Постановка задачи2:01
-
Состояние и жизненный цикл через useState и useEffect, рефы в функциональных компонентах, рефакторинг кликера, таймера и проекта с фильмами на новый стиль кода.
- Работа с состоянием в функциональном компоненте8:21
Знакомство с хуком useState, который заменяет классовое состояние в функциональных компонентах. Показано, как через деструктуризацию массива получать переменную состояния и функцию её обновления, задавать начальное значение и хранить данные разных типов. В демо кликер переписывается без объекта state и обращений через this.
- Решение практики по созданию кликера через функциональный компонент1:27
Практика по созданию кликера на функциональном компоненте. К обработчику инкремента добавляется декремент и кнопка с минусом, счётчик выносится в отдельный элемент разметки, блокам задаётся пара строк стилей. Заодно видно, как мало правок требует расширение уже работающего компонента.
- Управление жизненным циклом через функциональный компонент7:40
Разбор хука useEffect, покрывающего три главных этапа жизненного цикла: монтирование, обновление и размонтирование. На примере кликера, который монтируется и размонтируется по кнопке, показывается работа массива зависимостей: пустой список даёт однократный запуск, а переменная в списке — выполнение при каждом её изменении. Отдельно рассматривается функция очистки, которая срабатывает при размонтировании и отменяет таймеры и подписки.
- Использование рефов в функциональном компоненте8:23
Урок о хуке useRef: доступ к узлу через свойство current и хранение произвольных значений без вызова перерисовки. Показано отличие мутации рефа от обновления состояния и удобство записи туда, например, идентификатора интервала. Дополнительно разбирается функциональная форма обновления состояния, которая отталкивается от предыдущего значения и устраняет потерю обновлений.
- Решение практики по рефакторингу таймера в функциональный компонент16:23
Практика по переводу классового таймера на хуки. Счётчик и флаг работы переносятся в useState, идентификатор интервала размещается в рефе, значение сохраняется в localStorage, а вместо методов жизненного цикла применяются два эффекта с функциями очистки. В результате получается таймер, который помнит счёт между размонтированиями.
- Рефакторинг проекта с фильмами, часть 17:30
Первая часть перевода приложения с фильмами на функциональные компоненты: классовый компонент поиска переписывается на useState. Пропсы деструктурируются с заданием значения по умолчанию, из кода исчезают объект state и обращения через this, а обновляющие функции принимают готовое значение вместо объекта. После правок поиск и фильтры проверяются — приложение работает как прежде.
- Рефакторинг проекта с фильмами, часть 24:47
Завершение перевода приложения с фильмами на функциональные компоненты. Главный классовый компонент переписывается на useState, а логика монтирования переносится в useEffect с пустым массивом зависимостей; вызовы setState заменяются функциями обновления, включая управление флагом загрузки. В конце проверяется поиск и фильтрация — приложение целиком работает на хуках.
- Работа с состоянием в функциональном компоненте8:21
-
Отдельный урок о каждом хуке: useState, useEffect, useContext, useLayoutEffect, useCallback, useMemo, useImperativeHandle, useReducer, пользовательские хуки и правила их использования, плюс рефакторинг таймера на useReducer.
- useState8:55
Подробный разбор базового хука состояния: useState возвращает пару — значение и функцию обновления, которая принимает готовое значение либо функцию от предыдущего состояния. Начальным значением может быть функция: хук выполнит её сам, что удобно при чтении данных из localStorage. На примере объекта с двумя ключами видно, что обновляющая функция заменяет объект целиком, а не отдельные ключи, как классовый setState, поэтому под каждую переменную обычно заводят свой вызов хука.
- useEffect8:12
Итоговое занятие по useEffect: хук срабатывает асинхронно, не блокируя приложение, а массив зависимостей ограничивает, при каких обновлениях он запускается. Разобраны оформление нескольких эффектов с помощью комментариев или именованных функций и функция очистки, снимающая таймеры, интервалы, подписки и обработчики документа. Отдельно — реакция React на функцию, которая используется в эффекте, но не указана в зависимостях.
- useContext13:43
Урок показывает, как контекст избавляет от проброса пропсов через много уровней вложенности. Контекст создаётся через createContext, отдельный компонент с состоянием оборачивает props.children провайдером и кладёт в value данные вместе с методами, а компоненты на любой глубине достают их хуком useContext. Пример с коллекцией книг и методами добавления и удаления показывает, что подготовительная работа окупается при большой вложенности.
- useLayoutEffect6:00
Урок сравнивает useLayoutEffect с useEffect: синхронный аналог включается между перерендером виртуального DOM и отрисовкой браузерного, поэтому способен задержать вывод страницы. На примере кнопки со счётчиком показано, что обычный эффект даёт мигание промежуточного значения и скачки размера, а синхронный — два рендера при одной видимой отрисовке. Применять его стоит лишь при принудительном вмешательстве в готовый DOM; в остальных случаях по умолчанию выбирают асинхронный useEffect.
- useCallback, useMemo12:29
Разбор двух хуков мемоизации: useCallback кэширует саму функцию, не вызывая её, а useMemo — результат вычисления; оба пересчитываются лишь при изменении элементов массива зависимостей. Учитывается, что объекты, массивы и функции сравниваются по ссылке, поэтому при каждом перерендере даже одинаковые функции оказываются новыми. На примере двух кнопок показано, как связка useCallback с пустыми зависимостями и React.memo убирает лишние перерисовки, и когда мемоизация оправдана с учётом расхода памяти и ресурсов.
- useImperativeHandle7:27
Разбор хука, который вместе с forwardRef позволяет дочернему компоненту передать часть своей функциональности родителю — против привычного движения данных сверху вниз. Компонент оборачивается в forwardRef, а хук кладёт во внешний реф, в его ключ current, объект с методом — например, focus для поля ввода, к которому привязан внутренний реф. Демонстрация — валидация формы: при ошибке в длине номера карты или телефона поле обводится красным и получает фокус.
- useReducer10:57
Урок разбирает useReducer, устроенный как упрощённая модель Redux: редюсер принимает текущее состояние и действие, а по типу действия возвращает новое состояние. Хук подходит, когда один компонент ведёт множество связанных значений и одно действие требует нескольких обновлений сразу; события передаются через dispatch с ключом type и данными в payload. В примере заголовок меняет цвет по кнопкам: три useState и шесть обработчиков заменяются одним хуком, а вспомогательная функция удерживает каналы цвета в границах от 0 до 255.
- Пользовательские хуки6:58
Практика по пользовательским хукам: на примерах usePrevious и useLocalStorage показано, как стандартные хуки объединяются в переиспользуемую обёртку, пряча повторяемую логику и делая компонент компактнее. usePrevious возвращает значение с прошлого рендера — приём пригождается, например, в анимациях, а useLocalStorage читает хранилище по ключу и записывает туда каждое изменение. Готовые наборы таких хуков распространяются и отдельными NPM-пакетами.
- Правила использования хуков3:07
Урок объясняет два правила хуков: вызывать их только на верхнем уровне компонента, без условий, циклов и вложенных функций, и только внутри функциональных компонентов либо пользовательских хуков. React на каждом рендере ожидает тот же набор вызовов в том же порядке, поэтому хук, пропущенный из-за условия, ломает и его, и все последующие вызовы. Условие при этом переносят внутрь эффекта, а не вокруг вызова хука.
- Рефакторинг таймера с использованием useReducer7:18
Практический рефакторинг: таймер с двумя useState и лишним useRef переводится на useReducer, так что счёт и признак идущего отсчёта живут в одном объекте состояния. Редюсер разбирает события start, stop, reset и tick, а обработчики вместо установщиков состояния вызывают dispatch. Запись в LocalStorage не меняется, и после перевода таймер должен работать как прежде.
- useState8:55
-
Обзор API магазина, каркас с шапкой и футером, список товаров, состояние заказа, добавление и удаление товаров, изменение количества, подсказка о добавлении и публикация на GitHub Pages.
- Обзор API, что доступно, как использовать6:23
Знакомство с внешним API, на данных которого будет работать витрина: тарифы и лимиты запросов, состав доступной информации, регистрация и получение персонального ключа. Показано, что ключ передаётся в заголовке Authorization, а язык выдачи переключается GET-параметром lang. Запросы к сервису проверяются в Postman.
- Подготовка проекта, шапка и футер10:07
Практическая подготовка нового проекта: настройка расширений редактора, подключение стилей Materialize и иконок через CDN, хранение ключа API в локальном файле переменных окружения. Собирается каркас приложения из шапки, подвала и пустого компонента магазина.
- Вывод списка товаров18:47
Каталог выводится на хуках: состояние товаров и флаг загрузки через useState, запрос к API с ключом в заголовке Authorization внутри useEffect. На Materialize CSS собираются список и карточки товара с картинкой, описанием, ценой и кнопкой покупки; разбирается обработка пустого списка и ошибок запроса.
- Состояние заказа, иконка корзины7:37
Иконка корзины оформляется отдельным функциональным компонентом со счётчиком добавленных товаров; для постоянной видимости применяются фиксированное позиционирование и медиазапрос. Выясняется, что пока счётчик держится на статических заглушках, поэтому заводится состояние заказа и даётся задание о функции добавления товара.
- Решение: функция добавления товара в заказ11:47
Разбор решения: функция на уровне приложения пополняет состояние заказа — новая позиция создаётся при первом добавлении, а у существующей количество наращивается через findIndex и map. Функция спускается до карточки товара через пропсы и срабатывает по кнопке покупки.
- Создание корзины, пересчет суммы заказа в корзине19:20
Собирается корзина из компонентов списка и отдельной позиции: она открывается и закрывается по клику на иконку, окно центрируется через фиксированное позиционирование. Пустой заказ показывает заглушку, а итоговая сумма накапливается методом reduce без отдельного состояния.
- Функция удаления товара из корзины6:06
Добавляется удаление позиции по идентификатору: обновлённый заказ формируется фильтрацией прежнего, а функция через цепочку пропсов доходит до крестика у каждой записи. Попутно исправляется отображение цены позиции и добавляется CSS-анимация появления корзины.
- Решение: изменение количества товара в корзине7:34
Разбор самостоятельного задания: количество позиции меняют две отдельные функции, построенные на обходе заказа методом map, причём при уменьшении значение не уходит в минус. Роли элементов управления играют иконки плюс и минус из Material UI.
- Добавление подсказки о добавлении товара15:18
Приложение дополняется всплывающей подсказкой о добавлении товара: свой компонент алерта на useState и useEffect, где таймер прячет сообщение спустя три секунды, а функция очистки перезапускает отсчёт при повторных кликах. Штатный Toast из Material UI не используется, поэтому упрощённый вариант пишется самостоятельно.
- Публикация проекта на GitHub Pages8:53
Финал проекта: приложение собирается для production и публикуется на GitHub Pages — создаётся репозиторий с коммитами, ключ API переносится в секреты, устанавливается gh-pages и настраиваются скрипты публикации. В конце ссылка на репозиторий добавляется в шапку и подвал, а описание с демо попадает в README.
- Обзор API, что доступно, как использовать6:23
-
Создаёте контекст с провайдером, пишете редюсер с кейсами для корзины и переводите все компоненты магазина на получение данных и методов из контекста.
- Создание контекста с провайдером6:26
Создаём контекст магазина через createContext и компонент-обёртку с провайдером, который принимает children и передаёт значение всем вложенным элементам. Приложение оборачивается в провайдер, а вложенный компонент получает данные через useContext — цепочка пропсов на этом уровне становится не нужна.
- Создание редюсера, добавление первых кейсов8:20
Пишем редюсер как экспортируемую функцию со switch по типу экшена и вариантом по умолчанию, который возвращает стейт без изменений. Хук useReducer получает редюсер и начальное состояние магазина и отдаёт общий объект значений вместе с dispatch, а первые кейсы обрабатывают закрытие уведомления и удаление товара из корзины.
- Редьюсер корзины и методы контекста9:49
Разбираем готовое решение: методы магазина диспатчат события, а кейсы редюсера точечно обновляют единый стейт — добавление товара с количеством, изменение количества и показ корзины. В итоге логика приложения собирается в одном месте, компоненты остаются представлениями, а объект value несёт данные и методы для всех вложенных элементов.
- Переключение всех компонентов на контекст вместо пропсов15:44
Переводим компоненты магазина с пропсов на контекст: список товаров, корзина и корневой компонент берут данные и методы через useContext, а обновление списка товаров переезжает в редюсер. После рефакторинга корневой компонент сокращается со ста с лишним строк до нескольких десятков, и все функции магазина — добавление, корзина, уведомления — работают как раньше.
- Создание контекста с провайдером6:26
-
Строите SPA с рецептами: базовый и вложенный роутинг, компонент Link, хуки маршрутов, API базы рецептов, страницы категорий и рецепта, поиск и нюансы выкладки на продакшн.
-
Что такое SPA и как устроен проект, базовый роутинг, переходы через компонент Link, хуки useParams, useHistory, useLocation и useRouteMatch, вложенный роутинг.
- Роутинг и SPA, обзор проекта1:43
Знакомство с маршрутизацией на фронтенде и подходом SPA, при котором страницы сменяются без полной перезагрузки, а шапка и подвал остаются на месте. Разбирается история проектов React Router и Reach Router и объясняется, почему для нового проекта выбран React Router, у которого есть варианты для веба и мобильной разработки.
- Базовый роутинг11:40
Устанавливается React Router DOM и настраиваются маршруты для пробных страниц: компоненты Route связывают адреса путей с компонентами. Разбирается точное сравнение путей через exact, Switch, останавливающий перебор маршрутов после первого совпадения, и маршрут-заглушка Not Found для неизвестных адресов.
- Компонент Link3:53
Ссылки в шапке заменяются компонентом Link из React Router DOM: вместо href используется атрибут to, и переходы перестают перезагружать документ. Разбирается, почему Link не работает вне роутера, после чего роутер охватывает всё приложение; отсутствие новых сетевых загрузок проверяется во вкладке Network.
- Хуки useParams, useHistory9:22
Разбираются хуки useParams и useHistory: динамический параметр в пути позволяет одному маршруту обслуживать однотипные страницы, а useParams возвращает объект параметров текущего адреса. useHistory даёт методы переходов, на основе goBack собирается собственная кнопка возврата назад; упоминается и устаревший подход с withRouter.
- Хуки useLocation, useRouteMatch2:56
Завершение обзора роутер-хуков: useRouteMatch добавляет к параметрам признак совпадения адреса и текущий путь, а useLocation раскрывает адрес целиком — pathname, hash, search и state. Значения выводятся на страницу, и показывается, как из search извлечь get-параметры для логики приложения.
- Вложенный роутинг4:48
Теоретический урок о передаче пропсов маршрутизированному компоненту через Route с children вместо устаревшего пропа render и о вложенных маршрутах. В примере из документации useRouteMatch подставляет текущий путь в ссылки, а собственный Switch внутри раздела дорисовывает содержимое под неизменной общей разметкой; упоминается компонент Redirect для переадресаций.
- Роутинг и SPA, обзор проекта1:43
-
Обзор API с рецептами — что доступно и как использовать, и настройка методов запроса внутри приложения.
- Обзор API для проекта4:04
Обзор кулинарного API TheMealDB, доступного без регистрации: поиск блюда по имени, список по первой букве, детали по идентификатору, случайное блюдо и перечень категорий. Запросы проверяются в Postman, разбираются фильтры по категории, ингредиенту и области кухни, а также состав данных о рецепте с ингредиентами и их количествами.
- API настройка методов6:54
Ключ и базовый адрес API переносятся в конфиг, а в отдельном файле на fetch с async/await создаются асинхронные методы для получения категорий, фильтрации блюд по категории и запроса деталей по идентификатору. Каждый метод экспортируется и дальше применяется на страницах приложения.
- Обзор API для проекта4:04
-
Главная страница с категориями, страница категории с блюдами, страница рецепта, поиск на главной и нюанс выкладки SPA на продакшн.
- Главная страница с категориями13:26
Список категорий загружается из API в состояние компонента через useState и useEffect; пока данных нет, показывается Preloader. Категории выводятся сеткой карточек с картинкой, укороченным описанием и ссылкой на страницу категории, а грид-раскладка подстраивает колонки под содержимое.
- Страница категории с блюдами11:31
Имя из параметров маршрута становится ключом запроса к API, и полученный массив блюд выводится карточками со ссылкой на рецепт. Запрос выполняется в useEffect с зависимостью от имени, чтобы компонент перерисовывался при смене категории; попутно в API-модуле находится и исправляется ошибка с пропущенным await.
- Страница с рецептом24:21
По идентификатору из адреса загружается блюдо и превращается в страницу с крупной картинкой, инструкцией, встроенным видеороликом и таблицей ингредиентов, собранной перебором ключей объекта. Отдельно на странице категории появляется кнопка возврата назад на основе useHistory и goBack.
- Поиск на главной17:32
На главной странице появляется поиск с сохранением запроса в get-параметре адреса, чтобы ссылку с отфильтрованным списком можно было передать другому человеку. Управляемая форма отправляет значение наружу через callback, каталог фильтруется на фронтенде, а useLocation и useHistory обновляют адрес без перезагрузки; при открытии страницы параметр читается обратно.
- Нюанс выкладки на продакшн SPA-приложения3:24
Готовое SPA-приложение выкладывается на GitHub Pages: добавляются пакет gh-pages и скрипты predeploy и deploy. Из-за вложенного адреса маршруты перестают работать, и проблема решается опцией basename у BrowserRouter, после чего на живом сайте проверяются переходы, кнопка назад и поиск по ссылке с параметром.
- Главная страница с категориями13:26
-
Частые вопросы
Здесь собраны ответы почти на все вопросы, которые задают перед покупкой. Нажмите на вопрос, чтобы раскрыть ответ.
Об этом курсе
-
Да, базовый JavaScript нужен: первый раздел курса проверяет знания и подсказывает, где добрать пробелы, но сам язык с нуля здесь не разбирается.
-
Уроки показывают установку Node.js, редактора Visual Studio Code и расширения React DevTools. Дальше на выбор: локально через Create React App, ручная настройка со сборщиком Parcel или онлайн-песочница CodeSandbox — все три варианта разобраны.
-
Три приложения: поиск фильмов по API с фильтрами по категории, интернет-магазин с корзиной на контексте и редюсере и одностраничное приложение с рецептами и роутингом. Каждый проект доводится до публикации, магазин и SPA выкладываются на GitHub Pages.
-
Оба подхода. Сначала ядро React на классовых компонентах, затем отдельный раздел про каждый хук: useState, useEffect, useContext, useLayoutEffect, useCallback, useMemo, useImperativeHandle, useReducer, рефы и пользовательские хуки с правилами их использования.
-
В проекте с фильмами есть отдельный урок о безопасном хранении ключа: ключ выносится в env-переменные, чтобы не попасть в код, который уезжает на GitHub.
-
Компьютер с Windows, macOS или Linux, установленная платформа Node.js и редактор кода — установка показана в первом разделе. Данные берутся из бесплатных публичных API, свой сервер не нужен.
Доступ и материалы
-
Сразу после оплаты, в ту же секунду и автоматически. Ждать подтверждения не нужно. Доступ приходит двумя путями сразу. Первый: на почту, указанную при оформлении заказа, приходит письмо со ссылкой на материалы. Второй: та же ссылка появляется в вашем аккаунте на сайте, в разделе «Загрузки», и остаётся там постоянно.
-
Все видео и дополнительные файлы лежат в облачном хранилище. Ссылка на него — в вашем аккаунте на сайте, раздел «Загрузки», и в письме, которое пришло после оплаты. Аккаунт здесь — не формальность, а способ доставки: курс остаётся в нём навсегда. Даже если письмо потерялось или вы вспомнили о покупке через год, ссылка будет на месте.
-
Скачивать можно и нужно. Мы рекомендуем сохранить видео на компьютер и смотреть оттуда. Причина простая: облачное хранилище не рассчитано на просмотр видео. Иногда оно позволяет включить ролик прямо в браузере, но качество при этом заметно хуже исходного. На своём компьютере вы увидите курс таким, каким его записывали.
-
Бессрочно. Курс остаётся вашим навсегда, возвращаться к нему можно сколько угодно раз. Если через год или два ссылка вдруг перестанет открываться по техническим причинам — напишите на info@siluette.com.ua, мы её восстановим.
-
Прежде всего: доступ у вас есть в любом случае. Войдите на сайт и откройте раздел «Загрузки» — ссылка на курс уже там, независимо от того, дошло письмо или нет. Чаще всего письмо теряется из-за опечатки в адресе при оформлении заказа. Ещё стоит заглянуть в папку «Спам». Не разбирается — не тратьте время: напишите на info@siluette.com.ua или в чат в правом нижнем углу сайта, мы поможем.
-
Лучше всего на компьютере или ноутбуке: скачайте видео и откройте любым привычным плеером. Понадобятся установленные видеокодеки — на большинстве компьютеров они уже есть. Скачать курс можно на сколько угодно устройств. А вот телефон мы не советуем, и по двум причинам. На маленьком экране плохо видно детали, особенно если в уроке показывают интерфейс программы. И на телефонах часто нет кодеков для форматов, в которых записаны видео.
Оплата и возврат
-
Банковской картой Visa, MasterCard или Prostir, через Google Pay, Apple Pay, Masterpass, Visa Checkout, платёжный QR-код, Botpay в Telegram или Privat24. Есть и оплата частями: Монобанк (3 или 4 платежа), А-Банк (2, 3 или 4 платежа и рассрочка), Банк Глобус (8 платежей), «Скибочка» от OTP Bank (3 платежа), мгновенная рассрочка и оплата частями от ПриватБанка.
-
Да. Платёжная система принимает карты из Евросоюза и любых других стран. Одна деталь, о которой часто забывают: банк может попросить подтвердить платёж — в мобильном приложении или кодом из СМС. Если оплата не проходит, проверьте приложение банка и сообщения.
-
Добавьте в корзину два курса или больше — скидка применится автоматически ко всем товарам в корзине. Два курса: минус 20% на оба. Пять курсов: минус 20% на все пять. Скидка сочетается с любыми акционными ценами и действует на весь каталог без исключений.
-
Цифровые товары возврату и обмену не подлежат. Это общее правило для всех электронных товаров в Украине — постановление Кабинета Министров № 172 от 19 марта 1994 года. При этом мы всегда на связи. Если доступ не открывается, ссылка перестала работать или файлы повреждены — напишите на info@siluette.com.ua, укажите дату и номер заказа. Восстановим. Если что-то непонятно в самом курсе, тоже пишите — подскажем.
-
Пока нет. Мы работаем только с частными покупателями — безналичной оплаты по счёту от юридических лиц сейчас нет.
Как проходит обучение
-
Нет. Все курсы — это записи уроков для самостоятельного изучения: преподаватель не отвечает на вопросы и не проверяет домашние задания. Именно поэтому курсы стоят намного дешевле обучения с куратором. Вы получаете тот же материал, но занимаетесь сами и в своём темпе.
-
Да, цифровой сертификат — по запросу и бесплатно. Напишите на info@siluette.com.ua, укажите имя и фамилию ровно в том виде, в каком хотите видеть их в сертификате, и мы пришлём его в течение суток.
-
Для большинства курсов — нет. Они рассчитаны на начальный уровень и объясняют с азов. Если курс требует подготовки, это сказано в его описании.
-
Нет. Ни дедлайнов, ни расписания, ни сгорающего доступа. Скачали — смотрите когда удобно, с любыми перерывами.
-
Курс покупается для личного использования, и мы просим относиться к этому по-человечески: за каждым уроком стоит работа, а цена и так сильно снижена.
Поддержка
-
Лучше всего на info@siluette.com.ua. Есть и чат в правом нижнем углу сайта, но почта надёжнее: там можно всё описать подробно и приложить скриншоты. Просьба: опишите, что именно вы делали и что пошло не так, и приложите снимок экрана с ошибкой. Так мы решим вопрос сразу, а не будем полдня выяснять, что произошло.
-
В рабочее время, с 9:00 до 19:00, на почту обычно отвечаем в течение часа, в чате — за пару минут. После 19:00 тоже случается, но время ответа не обещаем.






Отзывы покупателей
25.06.2025 Подтвержденный клиент
Хуки - это было для меня самым сложным. После курса все встало на свои места. useReducer - это просто магия!
09.10.2024 Подтвержденный клиент
Это лучший курс по React для начинающих! Все разложили по полочкам, от JSX до хуков. Я прошел курс и сделал свое первое SPA. Я в восторге!
27.03.2024 Подтвержденный клиент
Я пробовал учить React самостоятельно, но запутался. Этот курс помог все систематизировать. Проект "Фильмы" - отличная практика.