Чем React Native отличается от гибрида и от нативной разработки

Стартовый вопрос почти любого собеседования по React Native: объясните, как это вообще работает и чем отличается от «сайта в обёртке».

React Native — фреймворк, в котором логика и описание интерфейса живут в JavaScript, а на экране при этом создаются настоящие нативные компоненты платформы, а не HTML внутри WebView.

Вопрос

«Чем React Native отличается от гибридных решений вроде Cordova и Ionic? А от нативной разработки на Swift и Kotlin? Правда ли, что RN компилирует JavaScript в нативный код?»

Что на самом деле проверяет интервьюер

Он проверяет не знание маркетинговых слоганов, а понимание модели исполнения: где выполняется ваш код, кто рисует пиксели и в какой момент между этими мирами появляется граница. От этого зависит всё остальное — почему одни вещи в RN быстрые, а другие тормозят, зачем нужны нативные модули и почему нельзя «просто» анимировать в JS.

Развёрнутый ответ

Гибрид на WebView: интерфейс — это веб-страница

Cordova, Ionic, Capacitor открывают внутри нативного приложения WebView и показывают в нём обычную веб-страницу. Всё, что вы видите, — это DOM: кнопка на экране является элементом <button>, стилизованным под платформу. Доступ к камере или геолокации идёт через плагины-мосты. Плюс — один код и мгновенный старт для веб-команды. Минус — интерфейс остаётся веб-интерфейсом: скролл, инерция, клавиатура и мелкая моторика жестов почти всегда ощущаются «не по-родному».

React Native: JS управляет нативными view

В React Native нет WebView. Ваш JS-код выполняется отдельным движком (Hermes, раньше — JavaScriptCore), а результат работы React — это описание дерева компонентов, которое нативная часть превращает в настоящие view платформы:

import { View, Text, Pressable } from 'react-native';

export default function Card({ title, onPress }) {
  return (
    <View>
      <Text>{title}</Text>
      <Pressable onPress={onPress}>
        <Text>Открыть</Text>
      </Pressable>
    </View>
  );
}

Компонент <Text> на iOS станет UILabel (точнее, специализированным подклассом текстового view), на Android — TextView. <View> превратится в UIView и ViewGroup. Поэтому скролл, ripple-эффект на Android, выделение текста и системная клавиатура работают ровно так, как их сделала платформа, — их не пришлось имитировать.

Компилируется ли JS в нативный код

Нет. Это самая частая ошибка в ответе. При сборке ваш JS собирается в один bundle (Metro), а Hermes дополнительно превращает его в свой байт-код, чтобы приложение стартовало быстрее. Но исполняет этот байт-код всё равно JS-движок внутри приложения. Компилируются нативная обвязка, сам движок и нативные модули — но не ваша бизнес-логика на JS.

Flutter — третий подход

Flutter не использует ни WebView, ни нативные компоненты: он рисует интерфейс сам, своим графическим движком, как игровой движок рисует кадр. Отсюда пиксель-в-пиксель одинаковый UI на обеих платформах и независимость от системных виджетов — но и необходимость догонять платформу вручную, когда та меняет поведение системных элементов.

Таблица-памятка

ПодходГде выполняется кодЧто на экране
Cordova / IonicJS в WebViewHTML и CSS
React NativeJS в Hermes или JSCНативные view платформы
FlutterСкомпилированный DartСобственная отрисовка движком
Swift / KotlinНативный кодНативные view платформы

Когда нативная разработка всё равно выигрывает

Честный ответ ценится больше, чем реклама фреймворка. React Native проигрывает, когда приложение построено вокруг тяжёлой графики и камеры в реальном времени, сложных жестов с непрерывной обратной связью, фоновой обработки данных, глубокой интеграции с системными фичами (виджеты, watch-приложения, расширения). Он выигрывает, когда логики много, а экраны типовые: списки, формы, карточки, авторизация — и когда команда одна на две платформы.

Типичные ошибки кандидатов

  • Говорят «RN — это тот же WebView, только удобнее». Это прямо неверно и сразу снижает доверие к остальным ответам.
  • Утверждают, что JS компилируется в Swift и Kotlin. Компилируется байт-код Hermes, а не платформенный код.
  • Обещают «100% общего кода». На практике общего кода обычно 80–95%, а остаток — платформенные настройки, разрешения, push, deep links и иногда нативные модули.
  • Не могут назвать ни одного минуса фреймворка. Интервьюер почти всегда ждёт трезвой оценки границ применимости.

Как ответить кратко

«В гибриде интерфейс — это веб-страница в WebView. В React Native интерфейс — настоящие нативные view: JS-код выполняется отдельным движком, Hermes, и описывает, какие компоненты и с какими свойствами показать, а нативная сторона их создаёт и обновляет. В нативный код JS при этом не компилируется — только упаковывается в bundle и в байт-код Hermes. Flutter — третий вариант: он вообще рисует UI сам. RN выгоден там, где много типового интерфейса и общей логики, и проигрывает на тяжёлой графике и глубокой интеграции с платформой.»

Проверьте себя
1. Что React Native создаёт на экране, когда вы используете компонент Text?
AHTML-элемент внутри скрытого WebView
BНастоящий нативный компонент платформы — UILabel на iOS и TextView на Android
CКартинку, отрисованную собственным графическим движком фреймворка
DCanvas, на котором JS вручную рисует текст
2. Кандидат говорит: «React Native компилирует JavaScript в нативный код». Что здесь неверно?
AНичего, это точное описание работы фреймворка
BJavaScript остаётся JavaScript и выполняется движком (Hermes или JSC) внутри приложения; компилируется только нативная часть проекта
CНа самом деле JS компилируется в Swift и Kotlin на этапе сборки
DJS компилируется, но только в release-сборке
3. Чем принципиально отличается подход Flutter от подхода React Native?
AFlutter тоже использует нативные view платформы, просто описывает их на Dart
BFlutter рисует интерфейс сам на своём графическом движке, не используя системные компоненты
CFlutter работает поверх WebView, как Cordova
DFlutter не поддерживает hot reload, в отличие от RN