Мок-собеседование по React: junior, middle, senior
Страница для фронтенд-разработчиков, которые готовятся к собеседованию по React на junior, middle или senior и хотят научиться объяснять React вслух, а не только читать о нём. ИИ-интервьюер спрашивает про рендеринг, hooks, стейт, производительность и новое в React 19, слушает ваши ответы и выдаёт отчёт с оценками за техническую точность, полноту и ясность.
О чём спрашивает ИИ на собеседовании по React
Рендеринг и reconciliation
Что вызывает ре-рендер, как React сравнивает дерево элементов, зачем нужны key и чем фаза render отличается от commit.
Hooks и эффекты
Правила hooks, зависимости и cleanup в useEffect, stale closures, useRef против state и почему эффект часто вообще не нужен.
Управление состоянием
Подъём стейта, Context и цена его ре-рендеров, useReducer, когда брать TanStack Query для серверных данных или Zustand и Redux Toolkit.
Производительность и мемоизация
React.memo, useMemo и useCallback, React Compiler, виртуализация списков, code splitting через lazy и Suspense, профилирование в React DevTools.
React 19 и Server Components
Actions, useActionState, useOptimistic, API use, ref как обычный prop и как Server Components и Server Functions делят работу между сервером и клиентом.
Concurrent rendering и Suspense
useTransition и useDeferredValue, границы Suspense для данных и кода, streaming SSR и ошибки гидрации.
Формы
Controlled и uncontrolled инпуты, form actions в React 19, валидация и когда оправдана библиотека вроде React Hook Form.
Тестирование и доступность
Тесты поведения через React Testing Library вместо деталей реализации, семантичный HTML, управление фокусом и ARIA в компонентах.
Вопросы на собеседовании по React: junior, middle, senior
Junior
Чем props отличаются от state?
Что должно быть в сильном ответе:Props передаёт родитель, и внутри компонента они только для чтения; state принадлежит самому компоненту и меняется через setter. Изменение и того и другого вызывает ре-рендер, но менять state может только его владелец. Хорошо добавить, что данные идут вниз через props, а изменения поднимаются вверх через колбэки.
Зачем React нужен key у элементов списка и почему индекс массива часто плохой key?
Что должно быть в сильном ответе:Key позволяет React сопоставить элементы между рендерами и сохранить, переместить или удалить нужные экземпляры компонентов вместе с их стейтом. Индекс ломается при вставке, удалении или сортировке: стейт и DOM, например значения инпутов, цепляются не к тому элементу. Нужен стабильный уникальный ID из данных; индекс допустим только для статичного списка, который не меняет порядок.
Как работает массив зависимостей useEffect и зачем нужна функция cleanup?
Что должно быть в сильном ответе:Без массива эффект выполняется после каждого рендера, с пустым массивом — один раз после монтирования, со значениями — когда любое из них изменилось по Object.is. Cleanup вызывается перед следующим запуском эффекта и при размонтировании: там снимают слушатели, чистят таймеры, отменяют запросы. Стоит упомянуть, что StrictMode в dev монтирует, размонтирует и снова монтирует компонент, чтобы выявить отсутствующий cleanup.
Чем controlled инпут отличается от uncontrolled?
Что должно быть в сильном ответе:Controlled инпут берёт value из state и обновляет его через onChange, так что единственный источник правды — React. Uncontrolled хранит значение в DOM, а прочитать его можно через ref или FormData при сабмите. Controlled удобен для мгновенной валидации и зависимых полей, uncontrolled проще и хорошо сочетается с form actions в React 19.
Почему hooks нельзя вызывать в условиях и циклах?
Что должно быть в сильном ответе:React различает hooks по порядку вызова внутри компонента, а не по имени. Если условие пропустит hook в одном рендере, все следующие hooks прочитают чужой сохранённый стейт. Hooks вызывают только на верхнем уровне компонента или кастомного hook, это проверяет eslint-plugin-react-hooks; исключение — новый API use, его можно вызывать условно.
Middle
Когда компонент ре-рендерится и как reconciliation решает, что обновить в DOM?
Что должно быть в сильном ответе:Компонент ре-рендерится, когда меняется его state, ре-рендерится родитель или меняется context, который он читает; новые props сами по себе не триггер — триггер это рендер родителя. Дальше React сравнивает новое дерево с предыдущим: другой тип элемента на том же месте — поддерево монтируется заново, тот же тип — обновляются props, детей в списках сопоставляют по key. В фазе commit в DOM попадает только разница.
Когда useMemo, useCallback и React.memo реально помогают, а когда бесполезны?
Что должно быть в сильном ответе:Помогают, когда вычисление действительно дорогое или когда стабильная ссылка спасает мемоизированного потомка от ре-рендера или эффект от лишнего запуска. Бесполезны, если потомок не обёрнут в memo, зависимости меняются каждый рендер или работа дешёвая — мемоизация тоже стоит ресурсов. Сильный ответ упоминает React Compiler, который добавляет мемоизацию автоматически, поэтому вручную её теперь ставят точечно, по данным Profiler.
Что такое stale closure в React-компоненте и как её исправить?
Что должно быть в сильном ответе:Функция, созданная во время рендера, захватывает props и state именно этого рендера; если интервал или слушатель продолжает её использовать, он видит старые значения. Варианты: добавить значение в зависимости эффекта, использовать updater-форму setCount(c => c + 1), держать актуальное значение в ref или вынести логику в useEffectEvent, чтобы читать свежие данные без перезапуска эффекта.
Какие проблемы с производительностью у Context и как вы организуете глобальный стейт?
Что должно быть в сильном ответе:Каждый потребитель ре-рендерится при изменении value, а новый объект-литерал в каждом рендере меняет его каждый раз. Решения: мемоизировать value, разделить контексты по частоте обновлений или взять стор с селекторами вроде Zustand или Redux Toolkit. Ещё стоит отделить серверный стейт (TanStack Query или загрузка данных фреймворка) от UI-стейта, который часто остаётся локальным.
Какую проблему решают useTransition и useDeferredValue?
Что должно быть в сильном ответе:Они помечают часть обновлений как несрочные, чтобы срочные, например ввод текста, оставались отзывчивыми, а медленный рендер можно было прервать. useTransition оборачивает обновление стейта, которое ты контролируешь, и даёт isPending; useDeferredValue возвращает «отстающую» копию значения, которое ты получаешь, например для фильтрации большого списка. Рендер они не ускоряют, а меняют его приоритет.
Senior
Чем Server Components отличаются от Client Components и где ты ставишь границу "use client"?
Что должно быть в сильном ответе:Server Components выполняются только на сервере, могут напрямую читать данные и не отправляют свой JavaScript в браузер, но у них нет state, эффектов и браузерных API. "use client" отмечает вход в клиентский бандл, и всё, что оттуда импортируется, становится клиентским кодом, поэтому границу опускают до мелких интерактивных листьев. Props через границу должны быть сериализуемыми, а Server Components можно передать в Client Component как children.
Страница в React-приложении тормозит. Как найдёшь и исправишь причину?
Что должно быть в сильном ответе:Сначала замер: React DevTools Profiler покажет, какие компоненты рендерятся, как часто и почему, а вкладка Performance и INP — стоимость взаимодействий. Типичные причины: широкие обновления context или стора, нестабильные props, ломающие memo, огромные списки, тяжёлая работа во время рендера. Исправление зависит от причины: опустить стейт ниже, разделить context или взять селекторы, виртуализировать списки, мемоизировать или положиться на React Compiler, code splitting, transitions для несрочных обновлений.
Что вызывает hydration mismatch и как streaming SSR с Suspense меняет гидрацию?
Что должно быть в сильном ответе:Mismatch возникает, когда серверный HTML отличается от первого клиентского рендера: Date.now, Math.random, форматирование по локали, чтение window или localStorage во время рендера, невалидная вложенность HTML. Лечится детерминированным первым рендером и переносом браузерных значений в эффект. При streaming границы Suspense отдают HTML частями и гидрируются независимо, а React в первую очередь гидрирует ту часть, с которой взаимодействует пользователь.
Как работают Actions в React 19 и что дают useActionState и useOptimistic?
Что должно быть в сильном ответе:Action — это async-функция, запущенная в transition, например переданная в prop action формы; React отслеживает pending, сбрасывает uncontrolled форму после успеха и передаёт брошенные ошибки в error boundary. useActionState оборачивает action и возвращает последний результат, функцию dispatch и isPending. useOptimistic показывает временное значение, пока action выполняется, и сам возвращается к реальному стейту после завершения.
Как бы ты построил стратегию тестирования для большого React-проекта?
Что должно быть в сильном ответе:Тестировать поведение, которое видит пользователь: React Testing Library с запросами по role и label, user-event для взаимодействий, сеть мокать через MSW, а не мокать hooks. Основная масса — компонентные и интеграционные тесты, небольшой набор e2e на Playwright для критичных сценариев, чистая логика — в unit-тестах. Стоит отдельно сказать, что запросы по role заодно ловят регрессии доступности.
Как проходит мок-собеседование по React
- Выберите React (и другие технологии из своего стека), свой уровень и язык собеседования: украинский, английский или русский. Или загрузите резюме и описание вакансии.
- Отвечайте на каждый вопрос голосом, как на настоящем собеседовании.
- Получите оценку каждого ответа по точности, полноте и понятности и отчёт со слабыми местами.
Как отвечать на вопросы по React вслух
- →Начни с ответа в одно предложение, потом — почему так, затем короткий пример из реального проекта: «такое было в дашборде, где каждое нажатие клавиши ре-рендерило всю таблицу».
- →Описывай код словами точно: назови hook, зависимость и триггер, например «setCount с updater-функцией, поэтому count не нужен в зависимостях эффекта».
- →Всегда добавляй trade-off. Сказать, когда НЕ стоит брать useMemo, Context или глобальный стор, звучит гораздо сильнее, чем перечислить, что они делают.
- →Привязывай ответы к версиям: «с React 18 обновления батчатся автоматически», «в React 19 ref — обычный prop». Это показывает, что ты в теме.
- →Если не уверен в деталях API, рассуждай вслух от модели рендера — что рендерится, когда и с какими значениями — вместо угадывания названий. Правильное рассуждение тоже засчитывается.
Частые вопросы
Собеседование основано на React 19?
Да, вопросы соответствуют актуальному React: hooks, concurrent-фичи и API React 19 — Actions, use, Server Components — плюс основы, которые не изменились. Если твой проект на более старой версии, загрузи вакансию или резюме, и вопросы подстроятся под твой реальный стек.
Можно тренироваться на вопросах из моей вакансии?
Да. Вместо выбора React можно загрузить описание вакансии или резюме, и ИИ построит собеседование под стек и уровень, которые там указаны, например React с Next.js и TypeScript.
Есть ли live coding?
Нет. Вопросы устные и концептуальные, отвечаешь голосом, редактора кода нет. Часть вопросов просит объяснить, как бы ты написал или отлаживал что-то, так что стоит потренироваться описывать код словами.
Сколько это стоит?
Первое собеседование до 5 вопросов бесплатное. Дальше оплата за каждое собеседование, от $1.75, до 50 вопросов. Подписки нет.