Продвинутый React и Redux
Базовые компоненты и хуки вы уже знаете; этот раздел — про управление данными и перерендерами в масштабе. Две большие части. Первая — инструменты самого React поверх props: context (доставить значение вглубь дерева без prop drilling), refs (императивный доступ мимо рендера), мемоизация (пропустить лишний перерендер) и паттерны переиспользования логики.
Вторая — Redux: предсказуемый контейнер состояния с однонаправленным потоком данных. Понимание Redux проверяют даже там, где его не используют, потому что он выражает общие принципы — неизменяемость, чистые редьюсеры, побочные эффекты в middleware. Сквозная ловушка всего раздела — идентичность ссылок: новый объект или функция на каждом рендере обнуляет и мемоизацию, и селекторы, и пропуск перерендера. Полная карта — в слоях ниже.
Карта темы
- Context — доставка значения вглубь дерева без prop drilling и цена перерендера потребителей.
- Refs — императивный escape-hatch к DOM-узлу или инстансу, переживающий рендеры и не вызывающий их.
- Мемоизация и перерендеры — что вызывает перерендер и как
Component/PureComponent/React.memoего пропускают. - Паттерны переиспользования — HOC и render props — три способа разделить сквозную логику и почему хуки вытеснили первые два.
- Поток данных Redux — store, actions, чистые reducers,
dispatchи однонаправленный цикл. - Middleware — слой между
dispatchи reducers, где живут побочные эффекты; thunk против saga. - Селекторы — мемоизированное вычисление производных данных через
reselect. - Нормализация состояния — уплощение вложенных данных в справочники по id ради дешёвых обновлений.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Новый литерал объекта как значение провайдера каждый рендер | Все потребители context перерендериваются впустую |
| Быстро меняющиеся данные (мышь, скролл) в context | Перерендер больших поддеревьев на каждое изменение |
Новый inline объект/массив/функция props у React.memo-ребёнка | Поверхностное сравнение видит изменение — пропуск рендера обнуляется |
Мутация вложенного объекта при PureComponent/memo | Поверхностное сравнение не замечает — UI не обновляется |
Ожидать перерендер от мутации ref.current | Ничего не происходит — refs намеренно вне рендера |
| Мутация state внутри reducer | Нарушена неизменяемость; подписчики не уведомляются корректно |
| Побочный эффект/async прямо в reducer | Reducer перестаёт быть чистым; место эффектов — middleware |
| Селектор строит новый объект на каждом вызове | Мемоизация обнуляется, подключённый компонент перерендеривается |
Значение для собеседований
Здесь проверяют системное мышление: понимаете ли вы, что перерендер и мемоизация держатся на идентичности ссылок, а Redux — на неизменяемости и чистоте редьюсеров. Кандидат, который говорит «побочные эффекты — в middleware, потому что reducer обязан быть чистым», показывает, что видит архитектуру, а не заучил API.
Что обычно проверяют:
- Какую проблему решает context и почему он не менеджер состояния и не замена props для всего.
- Что вызывает перерендер и что
React.memoсравнивает поверхностно, а не глубоко. - Разницу HOC, render props и кастомных хуков.
- Однонаправленный поток Redux и почему reducers чистые.
- Где в потоке место побочным эффектам (middleware) и чем thunk отличается от saga.
- Что такое мемоизированный селектор и зачем нормализовать state.
Типичный неверный ответ: «context — это замена Redux». Context лишь доставляет уже существующее значение вглубь дерева; он не хранит логику обновлений, не даёт middleware и при неаккуратной подаче значения перерендеривает всех потребителей.