Учебник по React с живыми примерами
Бесплатный учебник по React 19: компоненты, JSX, props, состояние, хуки и производительность. Каждый пример запускается прямо на странице: меняйте код и смотрите, как обновляются компонент и его консоль.
Начать пошаговый курс по ReactНачало работы
- Что такое ReactReact это библиотека JavaScript для построения пользовательских интерфейсов из компонентов. Вы описываете, что экран должен показывать для текущих данных, а React поддерживает страницу в актуальном виде, когда эти данные меняются.
- Установка ReactУстановите React, создав проект на Vite: проверьте Node.js, выполните одну команду создания, установите зависимости и запустите dev-сервер. Также о сгенерированных файлах, сборке для продакшена и о том, почему Create React App устарел.
- JSXJSX это расширение синтаксиса JavaScript, которое позволяет писать похожую на HTML разметку внутри компонентов React. Разберём его правила: один корневой элемент, закрытые теги, className, атрибуты в camelCase, фигурные скобки, инлайн-стили, комментарии и во что он компилируется.
- КомпонентыКомпонент React это функция JavaScript, которая возвращает JSX. Как писать и называть функциональные компоненты, собирать их в дерево, раскладывать по файлам, сохранять чистыми и чем компоненты отличаются от элементов.
- ПропсыПропсы это входные данные компонента React: значения, которые родитель передаёт дочернему компоненту как атрибуты JSX. Как передавать и деструктурировать пропсы, задавать значения по умолчанию, передавать функции, использовать spread и почему пропсы доступны только для чтения.
- Childrenchildren это пропс, в котором лежит всё, что вы помещаете между открывающим и закрывающим тегами компонента. Как строить с ним обёртки и макеты, передавать несколько слотов именованными пропсами, использовать children как функцию и когда API Children не подходит.
- ФрагментыFragment в React группирует несколько элементов в одно возвращаемое значение, не добавляя узел на страницу. Короткий синтаксис <>...</>, когда нужен <Fragment key> и почему фрагменты важны в таблицах и списках.
- Условный рендерингУсловный рендеринг в React это обычный JavaScript: инструкция if, тернарный оператор или && решают, какой JSX вернёт компонент. Каждый шаблон, лишний 0, который может вывести &&, возврат null и почему скрыть компонент не то же самое, что не рендерить его.
- Списки и ключиЧтобы отрендерить список в React, вызовите map() на массиве и верните JSX для каждого элемента, дав каждому элементу проп key. Filter перед map, откуда брать ключи и почему ключи-индексы путают элементы при изменении списка.
- СобытияСобытия React это пропсы вроде onClick и onChange, которые принимают функцию, а React вызывает её с объектом события, когда пользователь что-то делает. Как передать обработчик, а не вызвать его, передать аргументы, прочитать e.target.value и e.key, предотвратить перезагрузку формы и остановить всплытие.
- Стили в ReactКомпоненты React стилизуют через className и обычный CSS, через проп style для значений, вычисленных в JavaScript, через CSS Modules для изолированных имён классов или через утилитарные классы Tailwind. Каждый способ, условные классы и когда что выбирать.
Состояние и формы
- useStateuseState даёт компоненту значение, которое переживает повторные рендеры, и функцию-сеттер, которая перерисовывает экран при изменении значения. Синтаксис, функции обновления, объекты и массивы в состоянии и почему значение выглядит устаревшим сразу после установки.
- Обновление массивов и объектовЧтобы изменить массив или объект в состоянии React, создайте новый и передайте его в сеттер. Как добавлять, удалять, заменять, вставлять и сортировать элементы, обновлять вложенные объекты и почему мутация состояния оставляет экран без изменений.
- ФормыФормы в React на контролируемых полях: текстовые поля, textarea, select, флажки и переключатели, один объект состояния для многих полей, отправка через onSubmit, показ ошибок валидации и действия форм в React 19.
- Контролируемые и неконтролируемыеКонтролируемое поле получает значение из состояния React и меняется только через onChange. Неконтролируемое поле хранит своё значение в DOM, и вы читаете его через ref или FormData. Разница, частые предупреждения и когда что использовать.
- Подъём состоянияПодъём состояния означает перенос состояния из двух компонентов в их ближайшего общего родителя, который передаёт значение и сеттер обратно вниз как пропсы. Когда поднимать, как это сделать за три шага и когда лучше оставить состояние локальным.
- useReduceruseReducer хранит состояние и переносит каждое обновление в одну функцию-редьюсер: вы отправляете действие, а редьюсер возвращает следующее состояние. Синтаксис, как написать чистый редьюсер, пример со списком задач, ленивая инициализация и когда выбирать его вместо useState.
Эффекты и рефы
- useEffectuseEffect запускает код после того, как React обновил экран, чтобы компонент мог синхронизироваться с чем-то вне React: таймером, подпиской, обработчиком событий. Три формы массива зависимостей, функция очистки, бесконечные циклы и когда эффект вообще не нужен.
- Загрузка данныхЗагружайте данные в React, запуская запрос в useEffect, храня загрузку, ошибку и данные в состоянии и игнорируя ответы, которые пришли после изменения входных данных. async/await в эффектах, AbortController, состояния гонки и когда лучше взять библиотеку.
- useRefuseRef даёт компоненту коробку, `{ current }`, которая сохраняет содержимое между рендерами и не вызывает рендер, когда вы его меняете. Используйте её, чтобы добраться до узла DOM (фокус, прокрутка, измерение) или чтобы хранить id таймера или любое значение, которое экран не показывает.
- forwardRefforwardRef позволяет компоненту принять ref от родителя и прикрепить его к узлу DOM внутри. В React 19 функциональные компоненты получают `ref` как обычный пропс, поэтому новому коду forwardRef больше не нужен. Обе версии в работе, а также useImperativeHandle и типы TypeScript.
- useLayoutEffectuseLayoutEffect работает как useEffect, но выполняется сразу после того, как React обновил DOM, и до того, как браузер отрисует страницу. Используйте его, чтобы измерить элемент и подправить макет без видимого мерцания, а для всего остального оставьте useEffect.
Хуки и контекст
- Хуки ReactХук это функция, имя которой начинается с use и которая позволяет компоненту использовать возможность React: состояние, контекст, рефы или эффекты. Все встроенные хуки, сгруппированные по назначению, два правила, которым подчиняется каждый хук, и как написать свой.
- useContextuseContext читает значение, которое предоставляет родительский компонент, поэтому глубоко вложенный компонент получает его без того, чтобы каждый компонент между ними передавал его вниз пропсом. createContext, провайдеры, обновление контекста из дочернего компонента и как контекст влияет на повторные рендеры.
- Prop drillingProp drilling это передача пропса через компоненты, которые его не используют, только чтобы его мог прочитать компонент ниже. Пример, который можно запустить, почему это мешает по мере роста приложения и решения в том порядке, в каком их стоит пробовать: композиция, контекст, затем библиотека состояния.
- Пользовательские хукиПользовательский хук это функция, имя которой начинается с use и которая вызывает другие хуки, чтобы несколько компонентов могли переиспользовать одну и ту же логику с состоянием. Соберите useToggle, useLocalStorage, useDebounce и useWindowWidth и узнайте, почему каждый вызов получает собственное состояние.
- Правила хуковУ хуков два правила: вызывайте их на верхнем уровне компонента, никогда внутри условий, циклов или вложенных функций, и вызывайте только из функциональных компонентов или пользовательских хуков. Почему React нужен одинаковый порядок вызовов при каждом рендере и как исправить ошибки, когда он меняется.
- useIduseId возвращает уникальный стабильный id для каждого экземпляра компонента, чтобы подпись, поле ввода и подсказка aria-describedby могли ссылаться друг на друга, даже когда компонент появляется много раз. Почему Math.random и счётчики ломаются при серверном рендеринге и почему useId не для ключей списков.
- useSyncExternalStoreuseSyncExternalStore подписывает компонент на данные, которые живут вне React, например небольшой модуль-хранилище или API браузера вроде navigator.onLine, и рендерит его снова при каждом изменении этих данных. subscribe и getSnapshot, почему снимок нужно кэшировать и getServerSnapshot.
Рендеринг и производительность
- РендерингКомпонент React рендерится снова, когда меняется его состояние, когда рендерится его родитель или когда меняется контекст, который он читает. Разница между рендером и фиксацией, что на самом деле означает виртуальный DOM и как остановить ненужные рендеры.
- useMemouseMemo кэширует результат вычисления между рендерами и пересчитывает его, только когда меняются зависимости. Синтаксис, как сохранить объект стабильным для дочернего компонента с memo и когда useMemo того не стоит.
- useCallbackuseCallback возвращает одну и ту же функцию между рендерами, пока не изменятся зависимости. Он помогает, только когда эта функция передаётся дочернему компоненту с memo или используется как зависимость эффекта. Синтаксис, отличие от useMemo и ошибки, которых стоит избегать.
- React.memomemo оборачивает компонент так, что React пропускает его повторный рендер, когда пропсы поверхностно равны прошлым. Когда он помогает, почему новые объекты и функции в пропсах сводят его на нет и чего он не останавливает.
- useTransitionuseTransition помечает обновление состояния как несрочное, чтобы React мог сохранять отзывчивость страницы, пока в фоне рендерится медленная часть. isPending, startTransition, асинхронные переходы в React 19 и почему это не debounce.
- useDeferredValueuseDeferredValue даёт копию значения, которой разрешено отставать во время тяжёлых рендеров, поэтому поле ввода остаётся отзывчивым, пока медленный список догоняет. Как это работает, начальное значение в React 19 и сравнение с useTransition и debounce.
- Suspense и lazySuspense показывает запасной вариант, пока компоненты внутри не готовы, а React.lazy загружает код компонента только при его первом рендере. Разделение кода, вложенные границы, Suspense с use() в React 19 и обработка ошибок.
React 19 и продвинутые темы
- React 19React 19 добавил Actions, useActionState, useOptimistic, use, ref как пропс и метаданные документа, а 19.2 добавил Activity и useEffectEvent. Каждая возможность в работе, что было удалено и как обновиться.
- useActionStateuseActionState оборачивает асинхронное действие, хранит значение, которое оно вернуло последним, и сообщает, выполняется ли оно ещё. Сигнатура, действия форм, возврат ошибок валидации и вызов вне формы.
- useOptimisticuseOptimistic показывает ожидаемый результат, пока асинхронное действие ещё выполняется, а затем возвращается к настоящему состоянию, когда оно заканчивается, поэтому неудачный запрос отменяет себя сам. Синтаксис, форма с редьюсером и почему он должен выполняться внутри действия.
- Хук useuse читает значение промиса или контекста во время рендера. С промисом он приостанавливает компонент, пока не придут данные, и показывает ближайший запасной вариант Suspense. В отличие от других хуков, его можно вызывать внутри if и циклов.
- Границы ошибокГраница ошибок это компонент, который перехватывает ошибки, выброшенные при рендере компонентов внутри него, и показывает запасной UI вместо пустого экрана. Что она перехватывает, как написать её классом, как её сбросить и библиотека react-error-boundary.
- ПорталыcreatePortal рендерит часть компонента в другой узел DOM, например document.body, при этом она остаётся на том же месте в дереве React. Используйте его для модальных окон, подсказок и меню, которым нужно вырваться из overflow hidden и наложения z-index.
- Strict ModeStrictMode это обёртка, работающая только в разработке: она рендерит компоненты дважды, при монтировании выполняет setup, cleanup и снова setup эффектов и предупреждает об устаревших API, чтобы нечистые рендеры и пропущенные очистки проявлялись рано. В продакшене она ничего не делает.
- Жизненный цикл компонентаКаждый компонент React монтируется (появляется), обновляется (рендерится снова) и размонтируется (удаляется). Как каждая фаза соотносится с useEffect, методы жизненного цикла классов и их эквиваленты в хуках, а также фазы рендера и фиксации.
- Классовые компонентыКлассовый компонент это класс JavaScript, который наследует React.Component и возвращает JSX из метода render. this.props, this.state и setState, привязка обработчиков событий, методы жизненного цикла, PureComponent и как перевести класс в функциональный компонент.
Сравнения и собеседования
- Вопросы на собеседовании по ReactОколо 30 вопросов по React для собеседования от начального до продвинутого уровня, у каждого короткий ответ, который примет интервьюер, а для тех, что проще увидеть, чем прочитать, живой код.
- React или AngularReact это библиотека для UI, которую вы сочетаете с другими инструментами; Angular это полноценный фреймворк со встроенными маршрутизацией, формами, HTTP и внедрением зависимостей. Сравните одни и те же компоненты, написанные на обоих, рядом.
- React или VueReact и Vue это инструменты JavaScript для построения пользовательских интерфейсов из компонентов. Они различаются разметкой (JSX или шаблоны), тем, как реагируют на изменения (неизменяемое состояние и повторные рендеры или изменяемые реактивные ref), и тем, какая часть экосистемы официальная.
- React с TypeScriptКак типизировать приложение React на TypeScript: пропсы и children, useState с объединениями и null, useRef для элементов DOM, обработчики событий, контекст, обобщённые компоненты и пропсы нативных элементов.