Skip to content

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

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior React Native разработчик.

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

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

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

Вопросы

reactreact-native

React Native использует концепции React, но рендерит представления мобильных платформ вместо браузерного HTML.

  • Я работаю с View, Text и Pressable вместо элементов div, p и button.
  • Стили задаются JavaScript-объектами с подмножеством возможностей CSS, а не браузерной таблицей стилей с селекторами и каскадом CSS.
  • Я также учитываю safe area, кнопку «Назад» на Android, разрешения и сенсорный ввод.

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

reactreact-nativeoop

React Native требует помещать текстовые строки внутрь Text, а наследование текстовых стилей работает только в поддереве Text.

  • Строка непосредственно внутри View недопустима, поэтому перед выводом я оборачиваю её в Text.
  • Вложенный Text наследует от родительского Text цвет, семейство и размер шрифта, если не переопределяет их.
  • Стили View не переходят к дочернему Text, поэтому общую типографику нужно задать родительскому Text или передать явно.

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

htmlcomponents

JSX служит синтаксисом для описания дерева React-элементов внутри JavaScript или TypeScript.

  • Перед запуском приложения сборщик преобразует JSX в вызовы создания React-элементов.
  • Теги вроде View могут ссылаться на импортированные компоненты, а строчные HTML-теги вроде div не являются примитивами React Native.
  • JavaScript-выражения помещаются в фигурные скобки, например source={{ uri: avatarUrl }} или {name}.

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

Переданный родителем label является prop, а изменяющийся count хранится в state.

  • Props служат входными данными только для чтения, поэтому дочерний компонент не должен присваивать им новый label.
  • useState(0) хранит текущее значение count, а его setter запрашивает обновление.
  • Если count должен контролировать родитель, я передам count и callback onChange вместо дублирования состояния.

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

reactreact-native

Обновление состояния запланирует новый рендер компонента и сверку нового дерева с предыдущим.

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

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

styles

Я бы описал переиспользуемые стили через StyleSheet.create и объединил их в массиве с условным стилем.

  • StyleSheet.create создаёт именованные объекты стилей, например styles.card и styles.selectedCard.
  • Компонент может использовать style={[styles.card, selected && styles.selectedCard]}.
  • Более поздние элементы переопределяют совпадающие свойства, поэтому selectedCard может менять только borderColor или backgroundColor.

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

flexboxreactreact-native

Я бы использовал горизонтальный контейнер и задал обеим обёрткам кнопок flex: 1.

  • Контейнеру нужен flexDirection: 'row', потому что в React Native по умолчанию используется направление column.
  • Каждая обёртка с flex: 1 получит равную долю доступной ширины.
  • Свойство gap: 12 у контейнера создаст нужный интервал без отступов у каждой отдельной кнопки.

Зачем это спрашивают: Интервьюер оценивает практическое знание Flexbox, особенно направление column по умолчанию в React Native.

Числа раскладки React Native задаются в логических единицах, независимых от плотности, а не в физических пикселях.

  • Платформы преобразуют 100 единиц раскладки в разное число физических пикселей согласно плотности экрана.
  • Благодаря этому элемент сохраняет примерно одинаковый физический размер на разных устройствах.
  • Я использую PixelRatio только там, где действительно нужны данные о плотности пикселей, а не умножаю вручную каждое значение раскладки.

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

componentscss

Я бы оставил один компонент и выбрал только платформенное значение через API Platform.

  • Platform.select может вернуть { padding: 16 } для ios и { padding: 12 } для android.
  • Platform.OS подходит для небольшого условия с простыми ветками.
  • Если различается вся реализация, файлы Card.ios.tsx и Card.android.tsx могут иметь общий путь импорта.

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

Я бы получил отступы safe area и добавил нужное верхнее или нижнее пространство вокруг содержимого экрана.

  • react-native-safe-area-context предоставляет SafeAreaView и useSafeAreaInsets для актуальной кроссплатформенной обработки.
  • Я применяю только нужные дизайну края, чтобы вложенные навигаторы не добавляли один отступ дважды.
  • Я проверяю экран на iPhone с вырезом и Android с жестовой навигацией, потому что их отступы могут различаться.

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

typescriptcallbacksswift

Я бы описал тип props с обязательными строкой и числом и необязательной функцией.

  • Форма может содержать uri: string, size: number и onPress?: () => void.
  • Параметр компонента типизируется как AvatarProps, поэтому некорректный вызов не пройдёт проверку типов.
  • Значение size по умолчанию имеет смысл только после превращения size в необязательное поле; обязательному prop не нужен скрытый fallback.

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

hooks

Я бы хранил количество в useState и обновлял его функциональной формой setter.

  • const [quantity, setQuantity] = useState(1) даёт текущее значение и функцию обновления.
  • Увеличение использует setQuantity(current => current + 1), что безопасно при постановке обновлений в очередь.
  • Уменьшение использует Math.max(1, current - 1), поэтому ограничение состояния соблюдается внутри обновления.

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

hooks

Я бы запускал запрос в эффекте, зависящем от userId, и не позволял устаревшему запросу обновлять состояние.

  • Массив зависимостей содержит userId, поэтому переход с 42 на другого пользователя запускает новый запрос.
  • AbortController может отменить fetch в cleanup при размонтировании компонента или изменении userId.
  • Я веду loading и error state вокруг запроса, а не делаю саму функцию эффекта async.

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

memoization

useMemo может переиспользовать результат фильтрации, а useCallback сохраняет ссылку onSelect для мемоизированных строк.

  • useMemo заново фильтрует 500 элементов только при изменении исходного массива или текста фильтра.
  • useCallback возвращает ту же ссылку на onSelect, пока его зависимости не изменились, поэтому React.memo не перерисует строку только из-за нового обработчика.
  • Я добавлю эти хуки после профилирования: фильтрация 500 простых элементов может быть дешёвой, а мемоизация усложняет код и тоже требует работы.

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

forms

Я бы связал значение TextInput с состоянием и обновлял его через onChangeText.

  • value={email} делает React state источником истины для отображаемого текста.
  • onChangeText={setEmail} сохраняет каждое изменение без чтения браузерного объекта события.
  • После успешной отправки я вызываю setEmail(''), а после ошибки сохраняю текст пользователя для исправления.

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

reactreact-nativetouch-controls

Я бы передал функцию, которая вызовет save с id 7 при нажатии.

  • onPress={() => saveItem(7)} передаёт callback, а не результат saveItem.
  • Запись onPress={saveItem(7)} выполнит функцию во время рендера и передаст в onPress возвращённое значение.
  • Если обработчику нужны координаты нажатия, его аргумент event содержит nativeEvent, но id элемента берётся из замыкания или props.

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

Я бы обрабатывал состояния в понятном порядке приоритетов через ранние возвраты или одну явную ветку.

  • Во время loading показывается ActivityIndicator, чтобы пустой массив не выглядел как завершённое пустое состояние.
  • При ошибке показывается сообщение и действие для повторной попытки.
  • После успешной загрузки рендерится либо пустое состояние, либо список данных в зависимости от items.length.

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

reactindexes

Стабильный id сообщения позволяет React связывать отрендеренную строку с тем же сообщением после переупорядочивания.

  • Индекс массива меняется при вставке или перемещении сообщения, поэтому локальное состояние строки может перейти к другому элементу.
  • keyExtractor={item => item.id} даёт FlatList стабильный строковый ключ.
  • id должен быть уникальным среди соседних элементов; случайные ключи тоже плохи, потому что заставляют строки перемонтироваться при каждом рендере.

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

componentsuioop

Я бы оставил общую визуальную оболочку внутри Card, а переменное содержимое передавал через props или children.

  • children позволяет каждому экрану поместить собственные Text, Image или форму внутрь одной оболочки карточки.
  • Именованные props вроде footer или onPress могут явно описать общие слоты действий.
  • Это устраняет копирование стилей и не связывает Card с загрузкой данных или навигацией конкретного экрана.

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

react

Error boundary может заменить сломанное дочернее дерево запасным UI вместо потери всего экрана.

  • Он ловит ошибки рендера и lifecycle ниже своей границы, поэтому я размещаю его вокруг экрана или рискованного поддерева.
  • Базовый boundary по-прежнему реализуется классовым компонентом с lifecycle-методами ошибок либо берётся из проверенной библиотеки.
  • Он не ловит ошибки обработчиков событий и отклонённые async-операции, для которых нужен обычный try и catch.

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

Закрытые вопросы

  • 21

    Почему для checkout из 3 экранов Cart, Address и Payment подойдёт stack navigator?

    navigation
  • 22

    У приложения есть 4 главных раздела Home, Search, Saved и Profile; когда для них подходит tab navigator?

    navigation
  • 23

    Как ProductList должен открыть ProductDetails с productId 42 и безопасно прочитать этот параметр?

  • 24

    Корневой stack содержит навигатор HomeTabs; как уведомлению открыть экран Settings внутри вложенных вкладок?

    android-components
  • 25

    Что нужно настроить, чтобы URL myapp://product/42 открывал ProductDetails для товара 42?

    config
  • 26

    Экран вкладки остаётся смонтированным, пока открыта другая вкладка; как запускать аналитику при каждом получении фокуса?

  • 27

    На Android форма с несохранёнными изменениями должна запросить подтверждение перед уходом по одному нажатию аппаратной кнопки «Назад»; как это сделать?

    forms
  • 28

    В форме регистрации из 6 полей последнее поле скрывается клавиатурой; какую базовую раскладку стоит попробовать сначала?

    formsui
  • 29

    Кнопка только с иконкой удаляет одну фотографию; какие accessibility role и label ей нужны?

    mobile-accessibilitya11y
  • 30

    Строка настроек должна работать на английском и арабском; как обработать переведённый текст и раскладку справа налево?

    ui
  • 31

    Выполните GET /users/42 и превратите успешный JSON-ответ в объект пользователя; какие проверки обязательны?

  • 32

    DELETE /users/42 возвращает 204 No Content; как экран должен обработать ответ и удалить пользователя?

  • 33

    Стоит ли хранить видео размером 5 МБ или пароль аутентификации в AsyncStorage и для чего оно подходит?

    authpasswordsasync
  • 34

    Что managed workflow Expo берёт на себя для junior-разработчика первого приложения с уведомлениями и геолокацией?

    android-componentsexpo
  • 35

    Проект добавляет одну нативную библиотеку камеры, которой нет в Expo Go; почему нужен development build?

    expo
  • 36

    Пользователь один раз нажимает «Включить уведомления»; когда приложению запросить разрешение и как обработать отказ?

    permissionsandroid-components
  • 37

    Экран check-in требует одну фотографию и текущее местоположение; какие базовые шаги идут до использования обоих API устройства?

    api
  • 38

    Таймер должен приостанавливаться, когда приложение на 30 секунд уходит в фоновый режим; какой API жизненного цикла React Native вы используете?

    reactreact-nativeapi
  • 39

    Development и production сборки вызывают 2 разных базовых URL API; как настроить их без редактирования исходников перед каждой сборкой?

    configbuildapi
  • 40

    Почему секретный API-ключ платного сервиса нельзя положить в переменную EXPO_PUBLIC_ даже для одной release-сборки?

    secretsapiandroid-components
  • 41

    Как отрендерить 1 000 товаров через FlatList вместо помещения всех строк в один ScrollView?

    virtualized-lists
  • 42

    Удалённое изображение имеет размер 1200 на 800 пикселей, но должно поместиться в карточку шириной 300 пунктов; как разумно задать размер и кеширование?

    caching
  • 43

    Карточка должна за 300 мс плавно проявиться, изменив opacity с 0 до 1; как это сделать через Reanimated?

    cssanimationzero-to-one
  • 44

    Фотография должна двигаться по горизонтали вслед за пальцем и возвращаться после отпускания; что для этого даёт Gesture Handler?

    gesturesscaling
  • 45

    Составьте план теста через Jest и React Native Testing Library для LoginForm, где Submit включается только после заполнения 2 полей.

    jestrtltest-plans
  • 46

    Что проверит Detox или Maestro в одном release smoke flow, который открывает приложение, входит в аккаунт и показывает Home?

    end-to-end-testing
  • 47

    После добавления TypeScript-экрана что делает Metro при запуске React Native-приложения?

    reactreact-nativetypescript
  • 48

    Баг появляется только в одной release-сборке; чем она отличается от debug и какие современные инструменты использовать сначала?

  • 49

    Какой подписанный артефакт обычно отправляют в TestFlight и какие 2 типа Android-артефактов можно собрать?

    ios-distributionartifacts
  • 50

    Нужно изменить одну подпись кнопки в команде из 3 человек; опишите безопасный Git workflow от ветки до merge.

    git
  • 51

    Android-экран рисуется edge-to-edge, и белые иконки статус-бара пропадают на светлом изображении; как сохранить их читаемость без ещё одной обёртки safe area?

  • 52

    В форме входа есть поля email и пароля; как сделать так, чтобы кнопка Далее на клавиатуре переводила фокус на пароль, а Готово отправляла форму?

    formspasswords
  • 53

    У React Native Modal нет видимого действия закрытия, а аппаратная кнопка Назад на Android его не закрывает; как обработать все пути выхода?

    reactreact-native
  • 54

    Небольшой индикатор онлайн поверх аватара исчез после добавления скругления контейнеру изображения; как исправить раскладку?

    uicontainers
  • 55

    Двухколоночный экран профиля работает при размере 390 на 844, но обрезается после поворота до 844 на 390; как сделать его адаптивным?

    responsiveschema
  • 56

    После отправки появляется баннер ошибки, но пользователь TalkBack ничего не слышит и остаётся на кнопке Отправить; как объявить сбой?

    talkback
  • 57

    Когда система переключается в тёмную тему при открытом приложении, 6 подписей становятся тёмными на тёмном фоне; как исправить тему?

    themingsystem-design
  • 58

    Русский перевод увеличился с 2 до 4 строк и вытолкнул основную кнопку за пределы экрана высотой 667 пикселей; что вы измените?

  • 59

    После открытия модального окна с ошибкой фокус VoiceOver ещё 5 секунд остаётся на кнопке за ним; как исправить порядок фокуса?

    voiceover
  • 60

    Форма регистрации отправляет пустое имя и email из 5 неверных символов, а затем показывает только общую ошибку 400; как улучшить валидацию?

    genericsvalidationforms
  • 61

    GET /products возвращает ETag вместе с 200; как при повторном открытии отправить If-None-Match и обработать 304 через простой локальный кеш?

    cachinghttp-caching
  • 62

    Пользователь ищет cat, затем car, но более медленный ответ cat приходит последним и заменяет правильные результаты car; как защититься без AbortController?

  • 63

    REST-запрос может зависнуть на 45 секунд при слабой связи, но продукт требует показать таймаут через 10 секунд; как вы это реализуете?

    resiliencerest
  • 64

    API возвращает по 20 товаров, но два быстрых достижения конца списка дважды добавляют страницу 2; как исправить пагинацию?

    pagination
  • 65

    PDF-счёт скачан в локальный URI, но кнопка Открыть на Android ничего не делает; как дать пользователю открыть или поделиться файлом через Expo?

    expo
  • 66

    Встреча из ответа 2026-07-16T23:30:00Z показывает неверный календарный день у части пользователей после обрезания первых 10 символов; как это исправить?

  • 67

    Access token истекает через 30 минут, и следующий API-вызов возвращает 401; какую базовую обработку токена вы реализуете?

    tokensapi
  • 68

    Pull-to-refresh запускает второй запрос, пока первый 1,5-секундный refresh ещё идёт, а после ошибки индикатор не останавливается; как это исправить?

  • 69

    Endpoint обычно возвращает JSON, но proxy присылает HTML-страницу ошибки, и response.json() падает с Unexpected token <; как это обработать?

    htmlendpointsproxy
  • 70

    Пользователь загружает фото размером 12 МБ через медленную сеть и видит 0 процентов 20 секунд, а затем 100 процентов; как показать реальный прогресс?

  • 71

    Маршрут Products может не получить параметр sort, а неверный deep link может передать sort=cheapest-first; как выбрать безопасное значение по умолчанию?

    deep-linkingnavigation
  • 72

    После успешного входа Android Back возвращает с Home на экран Login; что нужно изменить в навигации?

    navigation
  • 73

    Экрану EditProfile нужна кнопка Save в заголовке native stack, но она отправляет имя из первого рендера; как связать её с текущим состоянием формы?

    forms
  • 74

    Экран Receipt открывается из Checkout или напрямую из уведомления, но его кнопка Закрыть вызывает goBack и ничего не делает, когда Receipt является корневым маршрутом; как обработать оба входа?

    android-components
  • 75

    Двойное нажатие по карточке товара за 300 миллисекунд открывает два одинаковых экрана Product; как остановить дубликат?

  • 76

    Badge вкладки Inbox остаётся равным 3 после того, как пользователь отметил все сообщения прочитанными; как синхронизировать его с navigator?

  • 77

    HomeTabs вложен в root stack, и каждая вкладка показывает два заголовка; как убрать повтор, не потеряв заголовки экранов деталей?

  • 78

    Приложение отмечает счёт как Отправлен сразу после открытия системного share sheet, даже если пользователь его закрыл; как смоделировать результат?

  • 79

    Закрытие DocumentPicker показывает Ошибка загрузки, а выбранное изображение размером 40 МБ всё равно уходит в endpoint только для PDF; как обработать оба исхода?

    endpoints
  • 80

    Кнопка Support открывает mailto:support@example.com, но на устройстве без настроенного почтового приложения ничего не происходит; какой fallback добавить?

    config
  • 81

    В FAQ есть 20 категорий, и заголовок текущей категории должен оставаться видимым при прокрутке вопросов; как построить это через SectionList?

    virtualized-lists
  • 82

    Строка настроек содержит иконку, заголовок, статус и chevron, но на нажатие реагирует только текст заголовка; как сделать составную строку одной доступной целью?

  • 83

    Нажатие строки 7 меняет selectedId, но FlatList не обновляет подсветку, потому что data не изменился; чего не хватает?

    virtualized-lists
  • 84

    Вкладка Feed сохраняет позицию списка, но повторное нажатие уже выбранной вкладки должно прокрутить FlatList вверх и сейчас срабатывает дважды после remount; как это реализовать?

    virtualized-lists
  • 85

    Изображение профиля использует signed URL, который истекает через 15 минут, и позже ломается, хотя сам аватар не менялся; как восстановить и кешировать его?

    caching
  • 86

    Анимация карточки длительностью 300 миллисекунд падает до 40 fps, когда ширина меняется на каждом кадре; как достичь 60 fps?

  • 87

    Горизонтальный swipe-to-delete внутри вертикального списка перехватывает жест уже после 2 пикселей диагонального движения; как разрешить конфликт?

    scaling
  • 88

    Countdown пишет лог каждую секунду даже после ухода с экрана, а возврат создаёт два countdown; какой cleanup нужен?

  • 89

    Запрос завершился и spinner исчез, но все видимые кнопки остались ненажимаемыми, потому что прозрачный полноэкранный View всё ещё смонтирован; как найти причину?

    ui
  • 90

    После добавления Products FlatList внутрь вертикального ScrollView появляется предупреждение о вложенных VirtualizedLists, а прокрутка работает нестабильно; как перестроить экран?

    virtualizationvirtualized-lists
  • 91

    Чистая функция formatDuration должна превращать 65 секунд в 01:05; как проверить её без рендера React Native компонента?

    reactcomponentsreact-native
  • 92

    Компонент товаров вызывает fetch и должен показать 2 элемента при 200 или ошибку при 500; как замокать эти случаи?

    componentsmocking
  • 93

    Какой один end-to-end сценарий докажет, что функция камеры обрабатывает отказ в разрешении, а после выдачи доступа начинает работать?

    permissionse2e
  • 94

    В production есть опечатка в подписи кнопки, а следующая задача добавляет новый нативный модуль штрихкодов; какое изменение можно отправить через EAS Update, а какому нужна новая store build?

    over-the-air-updates
  • 95

    Metro всё ещё импортирует старое имя модуля через 10 минут после переименования файла, хотя исходники правильные; что вы попробуете?

    metro
  • 96

    Экран камеры работает на iOS 18, но сразу закрывается на Android 14; как исследовать платформенный баг?

  • 97

    Релиз помечен как 1.4.0, но App Store Connect и Google Play отклоняют вторую загрузку с повторно использованными build identifiers; чем отличаются app version, iOS buildNumber и Android versionCode?

  • 98

    Release показывает старую иконку приложения и белую вспышку на 500 миллисекунд перед splash; что вы проверите?

  • 99

    Внутренний тестировщик сообщает о пустом экране только на Pixel 6 с Android 15 в build 108; какие данные вы соберёте до изменения кода?

  • 100

    Android-версия 1.4.0 с исправлением входа только что дошла до 5% rollout; какой один post-release smoke и monitoring сценарий вы выполните?

    monitoring