Перейти к содержимому

React: рендеринг, хуки и экосистема

React — это библиотека, которую все «знают» и которую мало кто понимает. Почти каждый разработчик может написать useState и вывести список через map, но когда интерфейс начинает «глючить» — список дёргается при вводе в поиск, эффект срабатывает дважды, форма перерендеривается на каждую клавишу, — начинается подгонка кода методом тыка. Разница между кодером и инженером на React ровно в одном: понимание того, что именно заставляет компонент перерендериваться и когда React решает это сделать.

В краткой версии учебника (v1) ты уже видел обзор хуков, управления состоянием и форм. В этом разделе мы идём глубже: под капот рендеринга, в ментальную модель эффектов, в trade-off’ы мемоизации, в границы применимости каждой библиотеки состояния. Это тот уровень, который отличает разработчика, прошедшего собеседование, от разработчика, которому не страшно дать ключевую фичу продукта.

Фундамент всего. Виртуальный DOM как представление UI в памяти, алгоритм reconciliation (сравнение деревьев), почему ключи — это не «просто айдишки», а вопрос корректности, и почему key={index} — прямая дорога к багам с потерей состояния. Отдельно разбираем батчинг обновлений: как React 18 сделал его автоматическим и в каких случаях это ломает привычные ожидания. Заканчиваем фазами render/commit и работой с Profiler — инструментом, который превращает догадки «кажется, тут тормозит» в измерения.

Два хука, на которых стоит 90% React-кода. Разбираем ментальную модель useEffect как синхронизации с внешними системами (а не «lifecycle-метод после рендера»), зависимости и линт-правила, race conditions в запросах и AbortController как штатное решение. Отдельный блок — «когда эффект не нужен»: производные состояния, которые многие выносят в стейт и эффекты, хотя они должны считаться прямо в рендере.

Самая недопонятая четвёрка хуков. Референциальная стабильность — главная причина использовать мемоизацию (а не «ускорение вычислений»), и мы на примерах покажем, когда useMemo/useCallback бесполезны и даже вредны. useRef как мутабельная ячейка, переживающая рендеры, включая callback-форму атрибута ref. useReducer — dispatch-модель, которая масштабирует локальное состояние лучше пачки связанных сеттеров.

Инструменты редкие, но решающие конкретные проблемы: измерения DOM без визуального «прыжка», доступные связи label/input через useId, неблокирующие обновления для тяжёлых списков через useTransition. Плюс контракт кастомных хуков — главного механизма переиспользования логики в React: разберём useLocalStorage, useMediaQuery и useDebounce как эталонные примеры.

Главная классификация, которую нужно принять до выбора библиотеки: локальное, серверное, URL- и глобальное состояние — четыре разных зверя. Zustand для клиентского глобального состояния без провайдеров, Redux Toolkit — когда оправдан его вес и инфраструктура, TanStack Query — серверное состояние (кэш, дедупликация, инвалидация), за который раньше отвечали ручные useEffect + fetch. Сравниваем по коду, а не по README.

Почему неконтролируемые формы рендерятся быстрее контролируемых, как register следит за DOM без ре-рендеров на каждую клавишу и что делать с компонентами-библиотеками через Controller. React Hook Form + Zod: схема как источник правды, вывод типов через z.infer, кросс-филдовая валидация через refine и async-проверки с сообщениями из сервера.

Data routers (createBrowserRouter) изменили философию: данные грузятся до рендера через loader, мутации уходят через action, состояния навигации читаются из useNavigation, а ошибки ловятся в errorElement. Разбираем, как это стыкуется с TanStack Query, чтобы не было двух систем данных в одном приложении.

Философия Testing Library — тестировать поведение, а не имплементацию: запросы по ролям, userEvent вместо fire-and-forget fireEvent, findBy* для асинхронщины, MSW для сетевого слоя. И честный список того, что тестировать не нужно, — чтобы тесты оставались активом, а не балластом.

Порядок глав важен: механика рендеринга из первой главы — это ключ к пониманию всего остального. Хуки (главы 2–4) читай подряд и пиши примеры руками, наблюдая ререндеры через React DevTools. Главы 5–7 — прикладные: бери по мере надобности, но прочитай все, чтобы выбор инструмента был осознанным, а не «что первым в голову пришло». Глава 8 закрепляет всё тестами.

В конце раздела у тебя будет полный набор знаний для пет-проекта: формы с валидацией, роутинг с загрузкой данных, кэширование серверного состояния и юнит-тесты. Дальше — сборка приложения и первая оптимизация бандла в разделе о сборщиках.