React
Для чего модуль
Перейти от уровня «знаю хуки» к уровню «могу проектировать и защищать React-решение под production-нагрузку».
Результат после прохождения
- Вы понимаете, почему компонент ререндерился, и доказываете это через инструменты.
- Вы проектируете state-границы так, чтобы UI был предсказуемым и поддерживаемым.
- Вы избегаете типичных async/effect ошибок и stale-data багов.
- Вы связываете оптимизации с метриками UX, а не с «красивым кодом».
Термины и аббревиатуры
| Термин | Коротко |
|---|---|
Reconciliation | Сравнение virtual tree |
Hook | API React для логики |
Stale closure | Устаревшие значения в замыкании |
Memoization | Кэш вычислений/рендера |
Hydration | Активация клиентского UI |
Фокус по грейдам
Junior: понимать базовые механики и объяснять их простыми примерами.Middle: применять тему в продуктовых сценариях с учетом рисков и ограничений.Senior: управлять архитектурными trade-offs, метриками и эволюцией решения.
Как работать с модулем
- Каждый урок проходите через mini-case из реального экрана.
- Для каждого решения фиксируйте: симптом -> гипотеза -> замер -> изменение -> результат.
- Любую оптимизацию проверяйте profiler/метриками.
Программа модуля
Урок 1. Рендеринг и reconciliation
Цель: понимать рендер React как конкретную механику, а не «магический процесс».
Что происходит при обновлении
- React строит новое дерево элементов.
- Сравнивает с предыдущим (reconciliation).
- Применяет изменения в commit phase.
Ключевой вывод: оптимизировать нужно не «количество вызовов функций», а дорогие пересоздания/commit-операции.
key и стабильность идентичности
Нестабильный key (например, index в reorder-списке) приводит к remount и потере локального state.
{items.map((item) => (
<Row key={item.id} item={item} />
))}
Profiler: что смотреть
- Какие компоненты часто ререндерятся.
- Длительность render/commit.
- Почему ререндер произошел (props, state, parent render).
Где ломается в проде
- Использование
indexкакkeyв изменяемых списках. - Случайные remount из-за нестабильных ключей/условного дерева.
- «Оптимизация» без замера, которая усложняет код и не улучшает UX.
Мини-задача (обязательная)
Возьмите список с drag/reorder и сравните два варианта:
key=index и key=item.id.
Снимите profiler и объясните разницу в поведении и стоимости обновлений.
Что спросит интервьюер: почему компонент ререндерился и как вы это доказали.
Критерий готовности по уроку: вы можете объяснить любой ререндер через profiler-данные, а не через догадки.
Урок 2. Hooks и side effects
Цель: писать эффекты без гонок, утечек и скрытых зависимостей.
useEffect как синхронизация с внешним миром
Эффект нужен не «чтобы что-то выполнить после рендера», а чтобы синхронизироваться с внешним источником: сеть, подписки, таймеры, DOM APIs.
Зависимости и stale closures
Если зависимость не указана, эффект может читать устаревшие значения. Если зависимостей слишком много и они нестабильны, будет лишняя работа.
Асинхронные эффекты: cancel first
useEffect(() => {
const ac = new AbortController();
(async () => {
try {
const res = await fetch(`/api/search?q=${query}`, { signal: ac.signal });
const data = await res.json();
setItems(data.items);
} catch (e) {
if (e.name !== 'AbortError') setError(e);
}
})();
return () => ac.abort();
}, [query]);
Где ломается в проде
- Эффект с
[], который использует динамические значения. - Два параллельных запроса обновляют один state в неопределенном порядке.
- Cleanup отсутствует для подписки/таймера.
Мини-задача (обязательная)
Сделайте экран поиска с debounce + cancel предыдущего запроса. Зафиксируйте, как предотвращается stale UI.
Что спросит интервьюер:
когда массив зависимостей [] корректен, а когда это баг.
Критерий готовности по уроку: вы можете написать effect без race-condition и объяснить, почему он безопасен.
Визуальная проверка перед coding drill: React Effects: cleanup guard, затем missing dependency.
Урок 3. Управление состоянием
Цель: отделять local state, shared state и server state, чтобы не перегружать архитектуру.
State ownership
Главный вопрос: где должен жить источник истины.
- Локальный state - ближе к компоненту.
- Shared UI state - поднимаем на ближайший общий уровень.
- Server state - отдельные механизмы загрузки/кэширования/инвалидации.
Антипаттерн «глобальный store на все»
Проблемы:
- Сильная связанность модулей.
- Сложная отладка побочных эффектов.
- Ненужные ререндеры широких частей дерева.
Практика декомпозиции
Для сложного экрана выделяйте:
- State владения данными.
- State UI-представления.
- Derived data (мемоизируемое вычисление).
Где ломается в проде
- Дублирование одного и того же state в нескольких местах.
- Мутация объекта в store и «невидимые» изменения.
- Смешение server state и локального UI state.
Мини-задача (обязательная)
Возьмите экран фильтруемого каталога и разложите state по ownership: что локально, что shared, что server state, что derived.
Что спросит интервьюер:
когда Context достаточно, а когда нужен выделенный state-слой.
Критерий готовности по уроку: вы можете аргументированно описать state-архитектуру экрана и показать, где она защищает от регрессий.
Урок 4. Надежность и перформанс
Цель: проектировать UI, устойчивый к ошибкам, задержкам и частичным отказам.
Error boundaries и fail-safe UI
- Ошибка одного виджета не должна «ронять» весь экран.
- Пользователь должен получать внятный fallback, а не белый экран.
Loading/empty/error как часть контракта
Для каждого запроса заранее проектируйте 4 состояния: loading, success, empty, error. Это снижает количество «невидимых» багов на edge-cases.
Performance с привязкой к UX
- Сначала измеряем baseline.
- Оптимизируем конкретный bottleneck.
- Проверяем влияние на сценарий пользователя.
Где ломается в проде
- «Оптимизация» через
memo/useMemoбез эффекта на UX. - Отсутствие fallback при частичном падении API.
- Нет связи frontend ошибки с backend trace.
Мини-задача (обязательная)
Соберите perf-case: проблема рендера -> baseline -> изменение -> итоговый замер. Отдельно опишите error/fallback стратегию для этого экрана.
Что спросит интервьюер: почему ваша оптимизация реально улучшает UX, а не только «красиво выглядит в коде».
Критерий готовности по уроку: вы можете защитить React-решение через надежность и измеримый эффект на пользовательский сценарий.
Практика
Работайте через 4 проверяемых блока. Каждый блок заканчивается артефактом, который можно показать на интервью или code review.
| Блок | Ответить | Practice action | Readiness |
|---|---|---|---|
| Render and reconciliation | Middle q-1..q-2, Senior q-3 | Profiler report: список с reorder, сравнение key=index vs key=item.id, render/commit evidence до и после | Вы объясняете, почему произошел rerender/remount, где потерялся state и какой profiler signal это доказывает |
| Effects and async safety | Middle q-3..q-5, Junior async q-9..q-11 | React Effects: cleanup guard, затем free-practice: search screen with debounce, AbortController, empty/error states and stale-response reproduction | Вы до запуска описываете race-condition, cleanup timing, dependency trade-off и защиту от stale UI |
| State ownership and performance | Middle q-6..q-10, Senior q-5..q-7 | State ownership map для фильтруемого каталога: server data, local draft, derived data, UI-only state, rollback point | Вы объясняете, где живет источник истины, когда Context достаточен, где memoization вредна и как проверить регрессию |
| Reliability UI | Senior q-6, Senior q-10, Playbook q-7 | Reliability runbook: partial API failure, loading/empty/error/success states, fallback behavior, trace/debug signal | Вы показываете fail-safe UI, user-visible risk, monitoring signal и recovery action без "белого экрана" |
Если блок получает partial или not ready, не переходите к Next.js: повторите связанные вопросы и перепишите артефакт так, чтобы в нем были symptom -> cause -> fix -> verification.
Связь с треками и вопросами
- Треки: Junior трек, Middle трек, Senior трек.
- Вопросы: Middle q-1..q-10, Senior q-3, Senior q-5..q-7, Senior q-10.
- Route practice: Middle день 2-3, Senior день 4, Мосты практики:
React rendering and effects+React state and performance, React effect/state debug pack. - Повторение через 24 часа: один вопрос про render/key, один про effect cleanup, один про state ownership, один про reliability fallback.
Критерий готовности
Ready, если вы можете объяснить React-решение как инженерный кейс:
context -> symptom -> hypothesis -> measurement -> change -> verification;- rerender/remount объясняется через profiler evidence, а не догадки;
- async effect имеет cleanup/cancel strategy и не перетирает UI stale response;
- state ownership отделяет server data, local draft, derived data и UI-only state;
- reliability-case покрывает loading, empty, error, partial failure и recovery action.
Partial, если теория понятна, но нет измерения, runbook или working artifact.
Not ready, если ответ держится на "React сам обновит", "добавим useMemo" или "поймаем ошибку где-нибудь" без конкретной проверки.
Артефакты после модуля
- Profiler-отчет до/после по одному экрану.
- State ownership-документ для сложного UI.
- Search/effect stale-response reproduction with fix.
- Reliability runbook для UI-инцидента.
- Набор из 8 сильных interview-ответов по React с примерами.