Skip to content

Вопросы на собеседовании: React-разработчик

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.

Смотреть пример резюме: React-разработчик

Тренировка флешкарточками

Интервальное повторение · Hunter Pass

Вопросы

reactcomponents

Компонент должен вычислять одинаковый JSX из одинаковых props, state и context без побочных эффектов во время рендера.

  • Рендер может запускаться повторно, приостанавливаться или отменяться, поэтому сетевым запросам и подпискам не место в теле компонента.
  • Обработчики событий выполняют эффекты по действиям пользователя, а useEffect синхронизируется с внешними системами после commit-фазы.
  • Локально менять значения, созданные в текущем рендере, допустимо, но изменение общих объектов делает результат зависимым от порядка.

Зачем это спрашивают: Интервьюер проверяет понимание чистоты как требования повторяемой модели рендеринга React.

reactsnapshot

Каждый рендер видит зафиксированный снимок состояния, а его обновление планирует следующий рендер и не меняет текущий снимок.

  • Обработчик события сохраняет значения state из рендера, в котором он был создан.
  • Несколько чтений после setState в одном обработчике всё равно вернут старый снимок.
  • Если следующее значение зависит от предыдущего, следует использовать функциональный updater.

Зачем это спрашивают: Сильный ответ связывает семантику снимка с обработчиками событий и предсказуемыми обновлениями состояния.

hooks

React связывает состояние хуков с порядком их вызовов, поэтому этот порядок должен сохраняться между рендерами.

  • Вызов хука внутри условия, цикла или вложенной функции может сдвинуть позиции следующих хуков.
  • Недостаточно того, что ветка выполняется обычно, порядок должен сохраняться при любом возможном рендере.
  • Условную логику следует поместить внутрь callback хука или в отдельно отрисовываемый компонент.

Зачем это спрашивают: Интервьюер оценивает понимание механизма, лежащего в основе правил хуков.

hooks

Функциональный updater нужен, когда следующее состояние зависит от предыдущего.

  • React передаёт последнее значение из очереди в функцию вроде setCount(count => count + 1).
  • Это не даёт нескольким обновлениям в одном событии использовать один и тот же захваченный снимок.
  • Такой подход также убирает лишние зависимости, если мемоизированному callback состояние нужно только для вычисления замены.

Зачем это спрашивают: Интервьюер проверяет умение избегать ошибок со старым снимком в зависимых обновлениях.

hooksdependencies

useEffect синхронизирует компонент с внешней системой после того, как React применил изменения интерфейса.

  • Зависимости включают каждое реактивное значение, прочитанное эффектом, в том числе props, state и функции из компонента.
  • React сравнивает зависимости через Object.is и повторяет эффект после commit-фазы при изменении одной из них.
  • Пустой массив означает отсутствие реактивных значений, а не разрешение убрать зависимости для удобства.

Зачем это спрашивают: Сильный ответ описывает эффекты как синхронизацию и выводит зависимости из кода, а не выбирает их как ручные триггеры.

hooks

Cleanup должен отменять подписку, таймер, соединение или другую внешнюю работу, созданную setup-частью этого эффекта.

  • React выполняет cleanup перед повтором эффекта с новыми зависимостями и после размонтирования.
  • В Strict Mode для разработки дополнительный цикл setup и cleanup выявляет код, который не умеет безопасно переподключаться.
  • Cleanup должен использовать те же идентификаторы и ссылки на обработчики, которые зарегистрировал setup.

Зачем это спрашивают: Интервьюер проверяет, спроектированы ли эффекты как симметричная синхронизация без утечек ресурсов.

hooks

useLayoutEffect выполняется после обновления DOM, но до отрисовки браузером, а useEffect обычно запускается после неё.

  • Layout effect подходит для измерения DOM, которое должно сразу повлиять на видимую раскладку.
  • Поскольку он блокирует отрисовку, лишняя работа в useLayoutEffect ухудшает отзывчивость.
  • Следует предпочитать useEffect, если без layout effect пользователь не увидит неверный промежуточный кадр.

Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат обосновать блокирующий отрисовку хук вместо его использования по умолчанию.

useMemo кеширует результат вычисления между рендерами при неизменных зависимостях, но остаётся оптимизацией, а не семантической гарантией.

  • React выполняет функцию во время рендера, поэтому она должна быть чистой.
  • Фреймворк может сбросить кеш, поэтому корректность программы не должна от него зависеть.
  • Хук полезен, когда дорогое вычисление или стабильное производное значение измеримо сокращает работу.

Зачем это спрашивают: Сильный ответ отличает необязательную мемоизацию от постоянного состояния и обязательного поведения программы.

components

useMemo добавляет сравнение, расход памяти и сложность кода, если вычисление дешёвое или зависимости часто меняются.

  • Мемоизация примитивного вычисления редко помогает, поскольку примитив уже имеет стабильное сравнение по значению.
  • Одна всегда новая зависимость сбрасывает кеш при каждом рендере.
  • Оптимизацию следует применять после данных профайлера или для явно дорогого пути, а не к каждому выражению.

Зачем это спрашивают: Интервьюер оценивает понимание стоимости и отсутствие слепой мемоизации по шаблону.

memoization

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 создаёт риск рассинхронизации.

Зачем это спрашивают: Интервьюер оценивает выбор хранилища по требованиям к рендеру, а не по удобству.

components

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.

react

Reducer должен быть чистым, детерминированным и возвращать новое состояние, если переход меняет данные.

  • Нельзя изменять существующий state, поскольку React использует идентичность для обнаружения изменений.
  • Сетевым запросам, таймерам и логированию как побочным эффектам не место внутри reducer.
  • Для неизвестных action нужна явная политика, обычно возврат текущего состояния или исключение в режиме разработки.

Зачем это спрашивают: Сильный ответ называет контракт reducer, который делает переходы воспроизводимыми и тестируемыми.

hooks

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