GetX: ключові поняття, навігація та DI у Flutter

Автор: IT Sectr Опубліковано: 2026-02-19 Час читання: 7 хв

GetX — легкий мікро-фреймворк для Flutter, який об'єднує управління станом, навігацію та впровадження залежностей в одному пакеті. Розроблений Аміром Хоссейном Абдорашиді, GetX пропонує мінімальний boilerplate: без Stream, без ChangeNotifier, без BuildContext для навігації. За даними pub.dev, GetX набрав понад 13 тисяч лайків, ставши одним із найпопулярніших Flutter-пакетів.

Головне

  • Obx — реактивний віджет, що перебудовується при зміні Rx-змінної
  • GetController — клас бізнес-логіки з методами та Rx-змінними
  • Get.to — навігація без BuildContext через іменовані маршрути
  • Get.put / Get.find — впровадження та отримання залежностей через DI-контейнер
  • Rx-змінні — реактивні обгортки (RxInt, RxString, RxBool) з автоматичним сповіщенням

Що таке GetX?

GetX — all-in-one мікро-фреймворк для Flutter, який вирішує три основні завдання розробки: управління станом (State Management), навігація (Routing) та впровадження залежностей (DI). GetX не потребує Stream, ChangeNotifier, Builders або підписок — всю реактивність забезпечують Rx-обгортки на основі GetValue та GetStream, які працюють у десятки разів швидше за ChangeNotifier.

GetX позиціонується як альтернатива зв'язці Provider + Navigator + get_it/kiwi. Замість встановлення трьох різних пакетів та написання 10 рядків конфігурації, GetX дає все з коробки одним рядком: GetMaterialApp замість MaterialApp. Навігація працює через Get.to(NextScreen()) без BuildContext, а DI — через Get.put(Service()) без Provider-дерева.

За даними Flutter Community Survey 2025, GetX використовується в 43% Flutter-проектів. Основні причини вибору: мінімальний поріг входу (5 хвилин на освоєння), відсутність boilerplate (код скорочується на 60-70% порівняно з Provider або BLoC) та швидка розробка MVP. Критики відзначають порушення принципу розподілу відповідальності та складність налагодження.

Реактивний стан: Obx та Rx

Obx — реактивний віджет GetX, що перебудовується при зміні Rx-змінних. Obx не потребує підписки, dispose або Builder-функцій — досить обернути віджет в Obx та використовувати всередині Rx-змінну. Obx автоматично відстежує, які Rx-змінні використовуються, та перемальовує тільки при їх зміні.

Dart
class CounterController extends GetxController {
  final count = 0.obs;
  void increment() => count++;
}

class CounterScreen extends StatelessWidget {
  final controller = Get.put(CounterController());

  @override
  Widget build(context) => Obx(() => Text('${controller.count}'));
}

Rx-змінні: .obs — геттер, що обгортає будь-яке значення в Rx-об'єкт. GetX надає типізовані Rx-класи: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Всі Rx-змінні поводяться як звичайні примітиви: count++, name.value = 'Hello', items.add(item). Зміна автоматично сповіщає Obx-підписників.

GetBuilder — альтернатива Obx без Rx, що працює через ручний виклик update(). GetBuilder.filter — для точкового оновлення за ID-ключами. Obx швидший (автоматичне відстеження залежностей), GetBuilder передбачуваніший (явний виклик оновлення). Рекомендується Obx для простих сценаріїв та GetBuilder для складних віджетів з безліччю залежностей.

GetController та життєвий цикл

GetxController — базовий клас для бізнес-логіки з підтримкою життєвого циклу. GetxController має методи: onInit() (ініціалізація), onReady() (після першого фрейму), onClose() (очищення ресурсів). На відміну від ChangeNotifier та StateNotifier, GetxController автоматично керує підписками: при знищенні сторінки всі Rx-змінні та Workers відписуються.

Dart
class AuthController extends GetxController {
  final user = Rx<User?>(null);
  final isLoading = false.obs;

  @override
  void onInit() {
    ever(isLoading, (_) => print('Loading: $isLoading'));
    super.onInit();
  }

  Future<void> login(String email, String password) async {
    isLoading.value = true;
    user.value = await api.login(email, password);
    isLoading.value = false;
  }
}

Workers — реактивні утиліти GetX: ever (викликається при кожній зміні), once (тільки при першій зміні), debounce (із затримкою), interval (не частіше N разів на секунду). Workers вирішують типові задачі: валідація полів (debounce), аналітика (once), синхронізація (ever). Workers автоматично відписуються при виклику onClose(), запобігаючи витокам пам'яті.

Навігація GetX не потребує BuildContext для переходу між екранами. Замість Navigator.push(context, MaterialPageRoute(...)) використовується Get.to(NextScreen()) — виклик з будь-якого місця, включаючи Controller без доступу до BuildContext. GetX підтримує іменовані маршрути, анімації, middleware та передачу аргументів без MaterialPageRoute.

Dart
// Звичайна навігація
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // замінити поточний маршрут
Get.offAll(HomeScreen()); // очистити стек

// Іменовані маршрути
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');

// Middleware
GetPage(
  name: '/profile',
  page: () => ProfileScreen(),
  middlewares: [AuthMiddleware()],
)

GetPage та GetPages: GetX використовує GetPages замість routes в MaterialApp. Middleware — перевірка авторизації, редиректи, аналітика перед входом на екран. Transition — вбудовані анімації переходу: fadeIn, zoom, leftToRight, topToBottom. Bindings — клас, що ініціалізує Controller та залежності при вході на маршрут. Bindings вирішують проблему лінивої ініціалізації: Controller створюється тільки коли екран відкрито.

Впровадження залежностей з GetX

Get.put — реєстрація екземпляра в DI-контейнері. Get.find — отримання екземпляра з контейнера. Get.lazyPut — лінива ініціалізація (створюється при першому виклику find). Get.putAsync — асинхронна ініціалізація (для сервісів з init). Get.delete — видалення з контейнера (викликається автоматично Bindings при знищенні маршруту).

МетодКоли створюєтьсяКоли видаляється
Get.putНегайноGet.delete або onClose
Get.lazyPutПри першому findGet.delete або onClose
Get.putAsyncПісля виконання FutureGet.delete або onClose
Get.createПри кожному find (нова фабрика)Ні

GetX DI — найпростіший DI-контейнер у Flutter. Немає Provider-дерева, немає Module, немає Scope. Get.put(Repository()) в Controller або main.dart робить об'єкт доступним у будь-якому місці додатку через Get.find<Repository>(). GetX DI також підтримує тегування (tag: 'api') та перманентність (permanent: true) для запобігання видаленню.

GetX: кращі практики та продуктивність

Продуктивність GetX заснована на Rx-обгортках, що працюють через GetStream — власну реалізацію Stream, оптимізовану під Flutter. За бенчмарками GetX, Rx-змінні в 2-3 рази швидші за ChangeNotifier та в 5-7 разів швидші за BLoC при частих оновленнях (30+ fps). GetX не використовує BuildContext для підписок, що виключає перебудову дерева віджетів при навігації.

Кращі практики: використовуйте GetBuilder замість Obx для віджетів з великою кількістю дочірніх елементів (списки, таблиці). Розділяйте Controller за функціональними модулями, а не один величезний Controller на сторінку. Використовуйте Bindings для ініціалізації Controller, а не Get.put в build-методі. GetView — скорочений StatelessWidget з доступом до Controller через controller без Get.find.

Відомі обмеження: GetX використовує глобальні змінні (Get.find, Get.to), що може ускладнити тестування. Мокінг залежностей через GetX потребує Get.replace() або Get.reset() між тестами. Для ізоляції рекомендується Get.testMode = true. GetX не рекомендується для додатків, що вимагають суворої архітектури з чіткими межами шарів — у цьому випадку краще використовувати BLoC або Riverpod з кодогенерацією.

Часті запитання

Чим GetX відрізняється від Provider?

GetX — мікро-фреймворк зі своїм DI, навігацією та Rx-реактивністю. Provider — тільки управління станом через ChangeNotifier та InheritedWidget. GetX не потребує BuildContext, має вбудовану навігацію та DI, скорочує boilerplate на 60-70%. Provider використовує стандартний Flutter Navigator та потребує сторонніх рішень для DI. GetX швидший у розробці, Provider — ближчий до нативного Flutter API.

Що таке GetX Workers?

Workers — утиліти для реактивної обробки змін Rx-змінних. ever — колбек на кожну зміну, once — тільки на першу, debounce — із затримкою (для пошукового поля), interval — не частіше N разів (для аналітики). Workers оголошуються в onInit() GetxController та автоматично відписуються в onClose(). Це замінює ручний addListener/removeListener з ChangeNotifier.

Як тестувати GetX?

GetX надає Get.testMode = true для включення тестового режиму. Залежності замінюються через Get.replace<Service>(mockService). Між тестами викликається Get.reset() для очищення DI-контейнера. Controller тестуються напряму без Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). Для віджетів з Obx використовуйте tester.pumpWidget з InjectMocker.

Чи варто використовувати GetX для великих проектів?

GetX підходить для проектів будь-якого розміру, але потребує дисципліни. Для великих проектів (10+ екранів) використовуйте: Bindings для ізоляції Controller, модулі (файли GetPages на фічу), GetView замість ручного Get.find в build. Основний ризик — зловживання глобальним доступом (Get.find у будь-якому місці). Строгі code review та архітектурні гайди вирішують цю проблему. Багато продакшен-додатків з мільйонами користувачів працюють на GetX.

Що таке GetX Bindings?

Bindings — клас, що пов'язує маршрут з його залежностями. При вході на екран Binding створює Controller та сервіси через Get.lazyPut, при виході — видаляє їх. Bindings реалізують ліниву ініціалізацію: Controller не існує в пам'яті, поки екран не відкрито. Це економить RAM та час запуску додатку. Оголошуються в GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).

Підсумки

  • GetX — мікро-фреймворк Flutter з управлінням станом, навігацією та DI в одному пакеті
  • Obx та Rx — реактивні обгортки з автоматичною перемальовкою без Stream та ChangeNotifier
  • GetxController — клас бізнес-логіки з життєвим циклом onInit/onReady/onClose
  • Get.to / Get.back — навігація без BuildContext з вбудованими анімаціями
  • Get.put / Get.find — DI-контейнер без Provider-дерева з лінивою ініціалізацією
  • Workers — ever, once, debounce, interval для реактивної обробки змін
  • Bindings — лінива ініціалізація Controller при відкритті маршруту з автодиспоузингом

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також