Вопросы на собеседовании: React-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.
Смотреть пример резюме: React-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
Компонент должен вычислять одинаковый JSX из одинаковых props, state и context без побочных эффектов во время рендера.
- Рендер может запускаться повторно, приостанавливаться или отменяться, поэтому сетевым запросам и подпискам не место в теле компонента.
- Обработчики событий выполняют эффекты по действиям пользователя, а useEffect синхронизируется с внешними системами после commit-фазы.
- Локально менять значения, созданные в текущем рендере, допустимо, но изменение общих объектов делает результат зависимым от порядка.
Зачем это спрашивают: Интервьюер проверяет понимание чистоты как требования повторяемой модели рендеринга React.
Каждый рендер видит зафиксированный снимок состояния, а его обновление планирует следующий рендер и не меняет текущий снимок.
- Обработчик события сохраняет значения state из рендера, в котором он был создан.
- Несколько чтений после setState в одном обработчике всё равно вернут старый снимок.
- Если следующее значение зависит от предыдущего, следует использовать функциональный updater.
Зачем это спрашивают: Сильный ответ связывает семантику снимка с обработчиками событий и предсказуемыми обновлениями состояния.
React связывает состояние хуков с порядком их вызовов, поэтому этот порядок должен сохраняться между рендерами.
- Вызов хука внутри условия, цикла или вложенной функции может сдвинуть позиции следующих хуков.
- Недостаточно того, что ветка выполняется обычно, порядок должен сохраняться при любом возможном рендере.
- Условную логику следует поместить внутрь callback хука или в отдельно отрисовываемый компонент.
Зачем это спрашивают: Интервьюер оценивает понимание механизма, лежащего в основе правил хуков.
Функциональный updater нужен, когда следующее состояние зависит от предыдущего.
- React передаёт последнее значение из очереди в функцию вроде setCount(count => count + 1).
- Это не даёт нескольким обновлениям в одном событии использовать один и тот же захваченный снимок.
- Такой подход также убирает лишние зависимости, если мемоизированному callback состояние нужно только для вычисления замены.
Зачем это спрашивают: Интервьюер проверяет умение избегать ошибок со старым снимком в зависимых обновлениях.
useEffect синхронизирует компонент с внешней системой после того, как React применил изменения интерфейса.
- Зависимости включают каждое реактивное значение, прочитанное эффектом, в том числе props, state и функции из компонента.
- React сравнивает зависимости через Object.is и повторяет эффект после commit-фазы при изменении одной из них.
- Пустой массив означает отсутствие реактивных значений, а не разрешение убрать зависимости для удобства.
Зачем это спрашивают: Сильный ответ описывает эффекты как синхронизацию и выводит зависимости из кода, а не выбирает их как ручные триггеры.
Cleanup должен отменять подписку, таймер, соединение или другую внешнюю работу, созданную setup-частью этого эффекта.
- React выполняет cleanup перед повтором эффекта с новыми зависимостями и после размонтирования.
- В Strict Mode для разработки дополнительный цикл setup и cleanup выявляет код, который не умеет безопасно переподключаться.
- Cleanup должен использовать те же идентификаторы и ссылки на обработчики, которые зарегистрировал setup.
Зачем это спрашивают: Интервьюер проверяет, спроектированы ли эффекты как симметричная синхронизация без утечек ресурсов.
useLayoutEffect выполняется после обновления DOM, но до отрисовки браузером, а useEffect обычно запускается после неё.
- Layout effect подходит для измерения DOM, которое должно сразу повлиять на видимую раскладку.
- Поскольку он блокирует отрисовку, лишняя работа в useLayoutEffect ухудшает отзывчивость.
- Следует предпочитать useEffect, если без layout effect пользователь не увидит неверный промежуточный кадр.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат обосновать блокирующий отрисовку хук вместо его использования по умолчанию.
useMemo кеширует результат вычисления между рендерами при неизменных зависимостях, но остаётся оптимизацией, а не семантической гарантией.
- React выполняет функцию во время рендера, поэтому она должна быть чистой.
- Фреймворк может сбросить кеш, поэтому корректность программы не должна от него зависеть.
- Хук полезен, когда дорогое вычисление или стабильное производное значение измеримо сокращает работу.
Зачем это спрашивают: Сильный ответ отличает необязательную мемоизацию от постоянного состояния и обязательного поведения программы.
useMemo добавляет сравнение, расход памяти и сложность кода, если вычисление дешёвое или зависимости часто меняются.
- Мемоизация примитивного вычисления редко помогает, поскольку примитив уже имеет стабильное сравнение по значению.
- Одна всегда новая зависимость сбрасывает кеш при каждом рендере.
- Оптимизацию следует применять после данных профайлера или для явно дорогого пути, а не к каждому выражению.
Зачем это спрашивают: Интервьюер оценивает понимание стоимости и отсутствие слепой мемоизации по шаблону.
useCallback мемоизирует ссылку на функцию, а не результат её вызова.
- React возвращает прежнюю функцию, пока все зависимости равны по Object.is.
- Стабильная ссылка важна, когда функция передаётся мемоизированному дочернему компоненту или входит в зависимости другого хука.
- Хук не отменяет создание встроенного функционального выражения и не удешевляет выполнение callback.
Зачем это спрашивают: Интервьюер проверяет понимание ссылочной идентичности, а не общее описание useCallback как ускорителя функций.
useMemo кеширует вычисленное значение, а useCallback кеширует саму ссылку на функцию.
- useMemo(() => value, deps) сохраняет возвращённое значение.
- useCallback(fn, deps) концептуально равен useMemo(() => fn, deps).
- Оба хука оправданы при чувствительных к ссылкам потребителях или дорогой работе и требуют полного списка зависимостей.
Зачем это спрашивают: Интервьюер оценивает умение выбрать хук по тому, что именно должно сохранить ссылочную стабильность.
useRef хранит стабильный изменяемый объект между рендерами и также может указывать на DOM-узел под управлением React.
- Изменение ref.current не вызывает рендер, поскольку ref находится вне потока визуального состояния React.
- DOM refs позволяют выполнять императивные действия вроде фокуса, выделения и измерения.
- В ref можно хранить идентификатор таймера, если он нужен обработчикам, но не участвует в отрисовке.
Зачем это спрашивают: Сильный ответ охватывает доступ к DOM и постоянные невизуальные значения, не подменяя refs состояние.
Чтение или изменение ref.current во время рендера может сделать результат зависимым от скрытого изменяемого состояния и нарушить чистоту.
- React может повторять, перезапускать или отменять рендер, поэтому момент изменения ненадёжен.
- Инициализация под стабильной проверкой на null является узким допустимым случаем, если всегда создаёт эквивалентный объект.
- Обычные чтения и записи ref должны происходить в эффектах или обработчиках событий.
Зачем это спрашивают: Интервьюер проверяет соблюдение безопасного для конкурентного рендера подхода вместо использования refs как невидимых переменных.
Значение должно быть в state, если его изменение обновляет видимый интерфейс, и в ref, если оно нужно только для императивной или служебной логики.
- State планирует рендер и участвует в модели снимков React.
- Изменения ref происходят сразу, но React не наблюдает их для отрисовки.
- Дублирование одного источника истины одновременно в state и ref создаёт риск рассинхронизации.
Зачем это спрашивают: Интервьюер оценивает выбор хранилища по требованиям к рендеру, а не по удобству.
useContext читает значение ближайшего подходящего provider выше вызывающего компонента в отрисованном дереве.
- Provider определяется положением в дереве, а не файлом с объявлением компонентов.
- Provider, возвращённый тем же компонентом, не влияет на более ранний вызов useContext внутри него.
- При отсутствии provider React возвращает default value, переданное при создании context.
Зачем это спрашивают: Интервьюер проверяет точное понимание поиска provider и значения по умолчанию.
Потребитель рендерится снова, когда ближайший provider получает value, не равное предыдущему по Object.is.
- React.memo не блокирует передачу свежего значения context потребителю.
- Новый объект или функция имеют новую ссылку, даже если их содержимое выглядит одинаковым.
- Разделение несвязанных данных по разным context ограничивает число потребителей, затронутых обновлением.
Зачем это спрашивают: Сильный ответ связывает распространение context с идентичностью value и областью повторного рендера.
Такой объект получает новую ссылку при каждом рендере provider, поэтому все потребители видят изменение context.
- Мемоизировать объект стоит только тогда, когда поля и зависимости callback действительно могут сохранять стабильность.
- Разделение состояния и действий или нескольких context может эффективнее уменьшить распространение обновлений.
- Оптимизация provider особенно важна для широкого context с множеством часто рендерящихся потребителей.
Зачем это спрашивают: Интервьюер оценивает понимание идентичности value и умение рассматривать дизайн context, а не только поверхностный фикс.
useReducer централизует переходы состояния, когда несколько связанных значений меняются через определённый набор действий.
- Reducer получает текущее состояние и action, после чего возвращает следующее состояние.
- Dispatch описывает произошедшее событие, не раскрывая обновление каждого поля.
- Хук полезен для сложных локальных процессов, но сам по себе не делает состояние глобальным.
Зачем это спрашивают: Интервьюер проверяет понимание reducer как модели переходов состояния, а не возможности глобального store.
Reducer должен быть чистым, детерминированным и возвращать новое состояние, если переход меняет данные.
- Нельзя изменять существующий state, поскольку React использует идентичность для обнаружения изменений.
- Сетевым запросам, таймерам и логированию как побочным эффектам не место внутри reducer.
- Для неизвестных action нужна явная политика, обычно возврат текущего состояния или исключение в режиме разработки.
Зачем это спрашивают: Сильный ответ называет контракт reducer, который делает переходы воспроизводимыми и тестируемыми.
useReducer предпочтительнее, когда поля состояния образуют одну модель переходов и многие события меняют их вместе.
- Он хранит допустимые переходы в одном месте и предотвращает частичные комбинации связанных обновлений.
- useState остаётся понятнее для нескольких независимых значений с простыми заменами.
- Само наличие нескольких свойств в объекте ещё не оправдывает дополнительный код reducer.
Зачем это спрашивают: Интервьюер оценивает решение по сложности состояния, а не предположение, что reducer всегда лучше масштабируется.
Закрытые вопросы
- 21
Что делает функцию кастомным хуком?
hooks - 22
Разделяют ли два компонента состояние, если вызывают один и тот же кастомный хук?
componentshooks - 23
Как следует работать с зависимостями внутри кастомного хука?
hooksdependencies - 24
Что такое stale closure в React-хуке?
reacthooksclosures - 25
Что такое reconciliation в React?
react - 26
Как тип компонента и позиция в дереве влияют на сохранение состояния?
components - 27
Какую роль ключи играют в списках React?
react - 28
Почему индексы массива часто являются плохими ключами React?
reactindexes - 29
Как использовать key вне списка для сброса состояния компонента?
components - 30
Что означает термин virtual DOM в React?
reactdomvirtual-dom - 31
Чем различаются render и commit фазы React?
react - 32
Что делает React.memo?
react - 33
Почему props в виде объектов и функций часто лишают React.memo пользы?
react - 34
Как правильно подходить к оптимизации рендеринга React?
reactoptimization - 35
Что такое controlled input в React?
reactforms - 36
Что такое uncontrolled input и когда он полезен?
forms - 37
Почему React предупреждает о переключении input между controlled и uncontrolled режимами?
reactforms - 38
Какую задачу решает передача ref через компонент?
- 39
Что делает useImperativeHandle?
- 40
Как порталы React ведут себя в дереве React и дереве DOM?
reactdom - 41
Что такое React error boundary?
react - 42
Какие ошибки не ловит error boundary?
react - 43
Что концептуально представляет Suspense?
react - 44
Как размещение Suspense boundaries влияет на пользовательский опыт?
react - 45
Что означает concurrent rendering в React 18?
reactconcurrency - 46
Что startTransition сообщает React?
communicationreact - 47
Чем useTransition дополняет startTransition?
- 48
Для чего нужен useDeferredValue?
- 49
Что изменилось в automatic batching в React 18?
reactbatch - 50
Что Strict Mode React выявляет в режиме разработки?
react - 51
Как построить переиспользуемый модальный компонент, сохранив доступность и композицию?
components - 52
Нужна переиспользуемая таблица с сортировкой, выбором строк и настраиваемыми ячейками. Как вы её спроектируете?
algorithms - 53
Компонент страницы загружает данные, управляет фильтрами и диалогами и рисует все секции. Как вы его разделите?
components - 54
Как спроектировать input, который работает и внутри библиотеки форм, и как отдельное управляемое поле?
componentsformsdesign - 55
После изменения порядка редактируемого списка значения отображаются не в тех строках. Как найти и исправить ошибку?
react - 56
Компонент копирует props в state и иногда показывает устаревшие значения. Как его отрефакторить?
refactoringcomponents - 57
Как реализовать переиспользуемый хук поиска с debounce без возврата устаревших результатов?
hooksdebounce - 58
Нескольким компонентам нужно реагировать на появление элемента во viewport. Как вы построите custom hook?
reactcomponentshooks - 59
Ввод в одном поле заставляет перерендериваться весь дашборд. Как вы найдёте причину?
- 60
Когда стоит оборачивать компонент в React.memo и как проверить пользу?
reactcomponents - 61
Компонент фильтрует большую коллекцию при каждом render. Как решить, нужен ли useMemo?
components - 62
Мемоизированный дочерний компонент продолжает рендериться из-за нового callback. Добавите ли вы useCallback?
callbacksmemoization - 63
Context provider заставляет сотни consumers рендериться при изменении одной настройки. Как это исправить?
- 64
React-страница зависает при рендеринге тысяч выбираемых строк. Как её оптимизировать?
reactoptimization - 65
Фильтрация большой панели результатов делает управляемый input медленным. Как сохранить отзывчивость ввода?
responsiveforms - 66
Как выбрать между локальным state, Context, Zustand и Redux Toolkit для новой фичи?
state - 67
Команда копирует ответы API в Redux и вручную отслеживает загрузку и свежесть. Как это упростить?
stateapi - 68
Redux-фича хранит одни сущности вложенными в нескольких экранах, и обновления расходятся. Как это отрефакторить?
mlopsstaterefactoring - 69
Компонент с Zustand рендерится при каждом изменении store, хотя показывает одно поле. Как это исправить?
componentsstate - 70
Фильтры должны переживать обновление страницы и поддерживать ссылки для обмена. Где хранить их состояние?
- 71
Как реализовать состояния загрузки, пустого результата, ошибки и обновления для экрана на React Query?
reactqueries - 72
При быстрой смене фильтра поиска иногда показываются результаты старого значения. Как исправить гонку запросов?
- 73
Как добавить optimistic toggle в список React Query и не повредить кеш при ошибке?
querieslockingcaching - 74
Как реализовать бесконечную ленту активности без дублирования страниц и неконтролируемых запросов?
- 75
Экран Apollo Client отправляет дублирующиеся GraphQL-запросы и показывает устаревшие связанные сущности. Как это отладить?
graphql - 76
Mutation проходит успешно, но несколько экранов React Query продолжают показывать старые данные. Как спроектировать обновление кеша?
reactqueriesdesign - 77
Как построить форму с сотнями полей без ререндера всей страницы при каждом нажатии?
forms - 78
Поле username проверяется на сервере, и медленные ответы перезаписывают результат для нового ввода. Как это реализовать правильно?
validation - 79
Как реализовать форму заказа, где пользователь добавляет, удаляет и переставляет позиции?
forms - 80
Длинной форме настроек нужны autosave и защита от перезаписи изменений из другой вкладки. Как её спроектировать?
formsdesign - 81
Где разместить error boundaries в большом React-приложении?
react - 82
Ошибка из click handler не попадает в ближайший error boundary. Как её обработать?
react - 83
Error boundary маршрута продолжает показывать fallback после перехода к корректной записи. Как его сбросить?
react - 84
Как написать custom hook для общего WebSocket-соединения, которым пользуются несколько компонентов?
componentshookswebsockets - 85
Как реализовать useOnlineStatus, который работает с server rendering и несколькими consumers?
hooks - 86
Как протестировать форму входа через React Testing Library?
reactformsrtl - 87
Набор React Testing Library ломается после безобидных изменений разметки. Как сделать его устойчивым?
rtlreactrefactoring - 88
Компонент загружает данные при монтировании и повторяет запрос после mutation. Как протестировать асинхронный сценарий?
componentsasync - 89
Как протестировать custom hook, зависящий от React Query и Context provider?
reacthooksqueries - 90
Тест autocomplete с debounce нестабилен в CI. Как его стабилизировать?
debounceflaky - 91
Как сделать доступный custom select в React без нативного select?
react - 92
В React SPA маршрут меняется, но фокус клавиатуры остаётся на старой ссылке. Как это исправить?
react - 93
Форма отмечает неверные поля красной рамкой, но пользователи скринридеров не узнают об ошибках. Как это исправить?
forms - 94
Кликабельная карточка работает мышью, но не клавиатурой. Как реализовать её правильно?
- 95
Редко используемый график сильно увеличивает начальный React-бандл. Как загрузить его эффективнее?
react - 96
Страница Next.js сообщает о hydration mismatch только некоторым пользователям. Как найти и исправить причину?
hydrationnextjs - 97
Страница Next.js App Router отправляет слишком много JavaScript, потому что верхний компонент использует client state. Как её отрефакторить?
componentsnextjsjavascript - 98
Как выпустить рискованное изменение React-чекаута под feature flag и не оставить две неподдерживаемые реализации?
reactfeature-flags - 99
Пользователи сообщают о падении React, которое команда не может воспроизвести локально. Как исследовать его в production?
reactdebugging - 100
React-экран замедляется после повторной навигации и продолжает отправлять дублирующиеся события. Как найти и исправить утечку?
react