Як влаштований React Native «під капотом»
Як влаштований React Native «під капотом»
Навіщо ця стаття
У попередньому матеріалі йшлося про задачу: навіщо існує React Native і чим мобільний застосунок відрізняється від сайту. Тут — наступний крок: як загалом влаштоване середовище, у якому цей код живе.
Мета не в тому, щоб запам’ятати десяток внутрішніх назв з документації. Мета — отримати робочу картину в голові:
- хто виконує JavaScript;
- хто малює кнопки й тексти на екрані;
- як натискання пальцем доходить до обробника в коді;
- що робить програма-збирач під час розробки;
- чому інколи кажуть про «старий» і «новий» способи зв’язку між JavaScript і системою телефону.
Усе складне спочатку пояснюється звичайними словами. Технічні назви з’являються після інтуїції. Глибокі деталі сучасної внутрішньої перебудови React Native (окремі шари з довгими англійськими іменами) у цій статті лише окреслені; повний розбір буде в пізнішому матеріалі курсу.
Спочатку згадаємо браузер
У вебі ланцюжок знайомий.
Розробник пише React-компоненти
У коді з’являються елементи на кшталт «заголовок», «кнопка», «форма». Це опис бажаного вигляду сторінки.
Збирач (наприклад, Vite або webpack) готує файли для браузера
Код модулів збирається в набір файлів, які зручно віддати сервером.
Браузер завантажує сторінку
Він будує DOM — внутрішнє дерево об’єктів документа (абзаци, кнопки, поля вводу).
Користувач бачить пікселі
Браузер сам вирішує, як намалювати DOM на екрані. React не малює пікселі «вручну» — він каже браузеру, яким має бути дерево, і браузер оновлює його.
Важливий висновок: React і середовище малювання — різні ролі. React відповідає за логіку «що показати при якому стані». Середовище (браузер) відповідає за «як це виглядає на екрані насправді».
Та сама ідея в React Native
У React Native ролі подібні, але середовище інше.
Розробник знову пише React-компоненти
Логіка стану, пропсів, хуків — знайома. Натомість замість веб-тегів з’являються мобільні компоненти (про них — у наступних статтях про інтерфейс). На цьому етапі достатньо уявити: «екран зі списком поїздок і кнопкою “Додати”».
Окремий збирач готує JavaScript-код для телефону
У світі React Native найчастіше йдеться про Metro — програму, яка під час розробки збирає модулі TypeScript/JavaScript у вигляд, зручний для запуску в застосунку. Детальніше про Metro — окремий розділ нижче.
На телефоні працює вже не браузер, а зібраний застосунок
Усередині нього є місце, де виконується JavaScript, і місце, де операційна система малює свої елементи інтерфейсу.
Користувач бачить звичні «телефонні» кнопки й тексти
Не HTML-сторінку в рамці (у звичайному сценарії React Native), а елементи, які iOS і Android уміють малювати самі.
Дві «служби» всередині застосунку: логіка й малювання
Щоб розуміти, чому інколи інтерфейс «гальмує», а логіка — ні (або навпаки), зручно уявити дві служби, які працюють поруч.
Служба логіки
Служба малювання
У розмовній інженерній мові ці служби часто називають потоками (threads — «нитки» виконання всередині програми). Для курсу на старті достатньо формулювань:
- потік JavaScript (або «потік логіки») — місце, де крутиться JS-код;
- потік інтерфейсу (або «UI-потік») — місце, тісно пов’язане з малюванням екрана операційною системою.
Чому це важливо вже зараз, ще до написання складного коду:
- довга синхронна робота в обробнику натискання може «підвісити» відчуття відгуку;
- важкі списки й зображення навантажують і логіку, і малювання — цим займуться окремі статті про списки й продуктивність;
- анімації, які мають бути дуже плавними, інколи свідомо переносять ближче до малювання (окрема тема жестів і анімацій).
Повну модель з усіма допоміжними потоками й сучасними змінами не потрібно тримати в голові після цієї статті. Достатньо: логіка й малювання — різні обов’язки, і між ними є зв’язок.
Зв’язок між JavaScript і «телефонною» частиною
JavaScript у React Native не є мовою, якою операційна система напряму малює кожну кнопку «з нуля» у стилі HTML. Потрібен посередник: домовитися, що «компонент тексту в React» відповідає «системному тексту на iOS/Android», що натискання треба передати в JS-обробник, що зміна стану має оновити підписи на екрані.
Старіший спосіб: черга повідомлень
Довгий час у React Native переважала модель, яку зручно уявити як чергу листів між двома кабінетами.
- Кабінет JavaScript пише: «покажи текст “Зберегти”».
- Лист кладуть у чергу.
- Кабінет нативної (системної) частини читає лист і малює системний елемент.
- Користувач натискає.
- Нативна частина кладе у зворотну чергу лист: «було натискання».
- JavaScript читає лист і викликає функцію-обробник.
Такий асинхронний обмін (не все відбувається в одному миттєвому «дзвінку») історично називали мостом (bridge — міст між світами).
Новіший напрям: тісніший зв’язок
З часом екосистема пішла до моделі, де JavaScript і нативна частина можуть спілкуватися без такої товстої черги листів — швидше й передбачуваніше для складних жестів і оновлень інтерфейсу. У документації це часто збирають під загальною назвою нова архітектура (New Architecture).
Усередині цієї «нової архітектури» є кілька частин з окремими іменами (новий спосіб малювати дерево інтерфейсу, новий спосіб підключати модулі телефону тощо). На цьому етапі курсу їхні абревіатури запам’ятовувати не обов’язково. Достатньо знати:
Що відбувається після натискання кнопки
Розглянемо життєвий сценарій. На екрані є кнопка «Додати поїздку». Користувач торкається її. У коді (ще схематично) передбачено обробник на кшталт «викликати функцію при натисканні».
Нижче — спрощена послідовність. Реальний рушій має більше кроків і оптимізацій; для навчання важливий порядок думок.
Палець торкається екрана
Операційна система фіксує дотик у координатах екрана й визначає, який системний елемент його «спіймав» (наша кнопка).
Системна частина повідомляє шар React Native
Подія «натиснуто» має дійти до світу JavaScript, де описана реакція застосунку.
Виконується JavaScript-обробник
Наприклад: змінити стан, додати елемент у список у пам’яті, підготувати перехід на інший екран, почати запит до сервера.
React рахує, що змінилось у дереві інтерфейсу
Як і у вебі, React порівнює «як було» і «як стало» (ідея узгодження / reconciliation — знайома з React).
Шар React Native просить систему оновити екран
Системні тексти, списки, кнопки отримують нові підписи, з’являються нові рядки списку тощо.
Користувач бачить результат
Наприклад, відкрився екран форми або в списку з’явилась нова поїздка.
Хто виконує JavaScript: рушій
JavaScript потрібен рушій (engine) — програма всередині застосунку, яка розуміє мову JS і виконує її.
У браузері рушії свої (наприклад, у Chrome — один відомий рушій, у Safari — інший). У React Native на мобільних пристроях сьогодні зазвичай використовують Hermes — рушій, орієнтований саме на мобільні сценарії.
Порівняння з вебом:
| Браузер | React Native (типово) | |
|---|---|---|
| Хто виконує JS | Рушій браузера | Рушій усередині застосунку (часто Hermes) |
| Хто малює UI | Браузер (DOM) | ОС через шар React Native |
| Чи відкриває користувач URL | Так | Ні, відкриває встановлену програму |
Хто збирає код під час розробки: Metro
Поки пишуть код, потрібен інструмент, який:
- знаходить імпорти (
import … from '…'); - перетворює TypeScript на вигляд, зрозумілий рушію;
- швидко віддає оновлення після збереження файлу.
У React Native цю роль зазвичай виконує Metro.
Два режими: розробка і «як у користувача»
Під час навчання легко змішати два світи.
- Застосунок часто з’єднаний з комп’ютером розробника.
- Metro віддає свіжий код.
- Зручні повідомлення про помилки, інструменти відлагодження.
- Швидкість старту й мережа в офісі можуть не збігатися з реальним телефоном у метро.
- Код упакований у встановлюваний застосунок.
- Немає «підключення до вашого ноутбука».
- Важливі розмір, час запуску, поведінка без кабелю.
- Доставка оновлень пов’язана з магазинами додатків (і інколи з окремими схемами оновлення JS — пізніше в курсі).
Модулі можливостей телефону
Окремий шар — доступ до камери, файлів, сповіщень, геолокації. У JavaScript ці речі не з’являються «самі»; їх надають модулі, які з одного боку мають JS-API для розробника, з іншого — вміють викликати системні функції iOS/Android.
Готові модулі екосистеми
Власні модулі
На рівні архітектури зараз важливо лише: екран (UI) і можливості пристрою — сусідні, але різні двері з боку JavaScript. Обидві двері проходять через шар React Native / модулів, а не через DOM браузера.
Зв’язок із веб-React: що переноситься, а що ні
- Компонентне мислення, пропси, стан, хуки.
- Ідея «UI — функція від стану».
- Узгодження дерева при зміні стану.
- Багато підходів до організації коду й глобального стану (Redux тощо) — з адаптацією.
- TypeScript як спосіб описати дані й пропси.
- DOM-API (
document,windowу веброзумінні). - HTML-теги й CSS-файли браузера.
- Припущення, що «оновив сервер — усі одразу на новій версії» так само, як сайт.
- Деякі бібліотеки, які жорстко зав’язані на браузер.
Міні-проєкт: трасування натискання кнопки
Завдання
Код писати не обов’язково. Потрібен короткий текст (половина–одна сторінка), у якому простежується шлях події.
Сценарій. У майбутньому застосунку Nomad на екрані списку поїздок є кнопка «Нова поїздка». Користувач натискає її. У результаті відкривається екран форми створення поїздки (поки що можна уявити це як «змінився поточний екран» без деталей бібліотеки навігації).
Що має бути в тексті
Крок 1. Старт від пальця
Опишіть, хто першим дізнається про дотик — користувацький код React чи операційна система?
Крок 2. Шлях до JavaScript
Опишіть, як подія потрапляє у світ, де живуть обробники на TypeScript (своїми словами, без обов’язкових абревіатур).
Крок 3. Логіка застосунку
Що робить код після натискання в цьому сценарії (зміна стану / намір показати інший екран)?
Крок 4. Оновлення екрана
Хто в підсумку малює новий вигляд — браузер чи системний інтерфейс телефону через React Native?
Крок 5. Дві служби
Одним абзацом: що в цьому ланцюжку ближче до служби логіки, а що — до служби малювання.
Критерій «готово»
Текст може зрозуміти колега, який читав лише попередню статтю курсу. Якщо з’являється термін на кшталт «міст» або «Metro» — поруч є пояснення одним реченням.
- Першою реагує ОС.
- Подія передається через шар React Native у JavaScript.
- Обробник оновлює стан / навігаційний стан (логіка).
- React перераховує дерево; шар RN просить ОС показати новий екран.
- Логіка — JS; фінальні пікселі кнопки й екрана — малювання ОС.
Nomad: що з цього випливає вже зараз
Коду Nomad у цій статті ще немає. Але архітектурна картина вже накладається на продукт.
Список поїздок
Кнопка «Додати»
Фото й офлайн
Повільність
Окремий git-коміт у застосунок на цьому кроці не потрібен. Достатньо зберегти текст міні-проєкту поруч із майбутніми нотатками продукту (коли з’явиться Nomad — можна покласти в docs/).
Підсумок
React знову лише описує UI
Малює не браузер, а операційна система телефону через шар React Native.
Логіка й малювання — різні обов’язки
JavaScript переважно відповідає за логіку; системна частина — за те, що видно й відчутно на екрані.
Між ними є зв’язок
Раніше його зручно уявляти як чергу повідомлень; сучасний напрям — тісніший зв’язок. Деталі «нової архітектури» — пізніше.
Metro збирає JS під час розробки
Hermes (типово) виконує JavaScript на пристрої.
Натискання кнопки — шлях через ОС → шар RN → JS → знову на екран
Цей ланцюжок — основа міні-проєкту статті.
Наступна стаття порівняє Expo і класичний проєкт React Native (CLI) уже не одним абзацом, а як два практичні шляхи роботи з тією самою архітектурою, яку щойно розглянуто.
Практичні завдання
Базовий рівень
- Пояснити своїми словами різницю між службою логіки і службою малювання.
- Назвати роль Metro і роль Hermes (по одному реченню на кожну).
- Відповісти: чи малює React Native інтерфейс через HTML DOM у звичайному мобільному сценарії?
Середній рівень
- Виконати міні-проєкт (повне трасування натискання).
- Описати, що зміниться в трасуванні, якщо після натискання кнопки не змінюється екран, а лише текст на тій самій кнопці («Зберегти» → «Збережено»).
- Навести приклад важкої роботи, яку не варто синхронно виконувати прямо в обробнику натискання, і коротко чому.
Професійний рівень
- Порівняти (пів сторінки) модель «React → браузер» і «React → React Native → ОС» для колеги, який знає лише веб.
- Сформулювати три запитання, які варто поставити, якщо користувач каже: «Застосунок гальмує».
- Коротко пояснити, навіщо екосистемі був потрібен перехід від «черги листів» до тіснішого зв’язку — без переліку внутрішніх абревіатур.
Часті запитання
React Native — навіщо він потрібен
Зрозуміле введення в React Native для тих, хто вже знає React — які задачі він вирішує, чим відрізняється від сайту на телефоні, і коли його варто обирати
Expo і класичний React Native — два шляхи одного фреймворку
Зрозуміле порівняння Expo і React Native CLI — що це таке, чим відрізняються, і чому курс спочатку йде через Expo