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 создаётся только когда экран открыт.

Dependency Injection с 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: best practices и производительность

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

Best practices: используйте 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 реализуют lazy-инициализацию: 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-дерева с lazy-инициализацией
  • Workers — ever, once, debounce, interval для реактивной обработки изменений
  • Bindings — lazy-инициализация Controller при открытии маршрута с автодиспоузингом

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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