GetX — یک میکروفریمورک سبک برای Flutter که مدیریت وضعیت، ناوبری و تزریق وابستگی را در یک بسته ترکیب میکند. ساخته شده توسط امیرحسین عبدالرشیدی، GetX حداقل boilerplate را ارائه میدهد: بدون Stream، بدون ChangeNotifier، بدون BuildContext برای ناوبری. بر اساس دادههای pub.dev، GetX بیش از ۱۳ هزار لایک جمعآوری کرده و به یکی از محبوبترین بستههای Flutter تبدیل شده است.
مطالب اصلی
GetX — یک میکروفریمورک all-in-one برای Flutter که سه وظیفه اصلی توسعه را حل میکند: مدیریت وضعیت (State Management)، ناوبری (Routing) و تزریق وابستگی (DI). GetX نیازی به Stream، ChangeNotifier، Builder یا اشتراک ندارد — تمام واکنشگرایی توسط پوششهای Rx مبتنی بر GetValue و GetStream تأمین میشود که دهها برابر سریعتر از ChangeNotifier کار میکنند.
GetX به عنوان جایگزینی برای ترکیب Provider + Navigator + get_it/kiwi قرار میگیرد. به جای نصب سه بسته مختلف و نوشتن ۱۰ خط کانفیگ، GetX همه چیز را یکجا با یک خط ارائه میدهد: GetMaterialApp به جای MaterialApp. ناوبری از طریق Get.to(NextScreen()) بدون BuildContext کار میکند و DI — از طریق Get.put(Service()) بدون درخت Provider.
بر اساس Flutter Community Survey 2025، GetX در ۴۳٪ پروژههای Flutter استفاده میشود. دلایل اصلی انتخاب: حداقل آستانه ورود (۵ دقیقه برای یادگیری)، عدم وجود boilerplate (کد ۶۰-۷۰٪ در مقایسه با Provider یا BLoC کوتاهتر میشود) و توسعه سریع MVP. منتقدان به نقض اصل جداسازی مسئولیتها و دشواری دیباگ اشاره میکنند.
Obx — ویجت واکنشگرای GetX که با تغییر متغیرهای Rx بازسازی میشود. Obx نیازی به اشتراک، dispose یا توابع Builder ندارد — کافی است ویجت را در Obx بپیچید و از متغیر Rx در داخل استفاده کنید. Obx به طور خودکار ردیابی میکند که کدام متغیرهای Rx استفاده میشوند و فقط هنگام تغییر آنها بازنشانی میکند.
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 — getter که هر مقداری را در یک شیء 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 برای ویجتهای پیچیده با وابستگیهای متعدد توصیه میشود.
GetxController — کلاس پایه برای منطق کسبوکار با پشتیبانی از چرخه حیات. GetxController دارای متدهای: onInit() (مقداردهی اولیه)، onReady() (بعد از فریم اول)، onClose() (پاکسازی منابع). برخلاف ChangeNotifier و StateNotifier، GetxController به طور خودکار اشتراکها را مدیریت میکند: هنگام نابود شدن صفحه، همه متغیرهای Rx و Workers از اشتراک خارج میشوند.
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 پشتیبانی میکند.
// ناوبری معمولی
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 به جای routes در MaterialApp از GetPages استفاده میکند. Middleware — بررسی احراز هویت، تغییر مسیرها، تحلیل قبل از ورود به صفحه. Transition — انیمیشنهای داخلی انتقال: fadeIn، zoom، leftToRight، topToBottom. Bindings — کلاسی که Controller و وابستگیها را هنگام ورود به مسیر مقداردهی اولیه میکند. Bindings مشکل مقداردهی اولیه تنبل را حل میکنند: Controller فقط زمانی که صفحه باز است ایجاد میشود.
Get.put — ثبت نمونه در کانتینر DI. Get.find — دریافت نمونه از کانتینر. Get.lazyPut — مقداردهی اولیه تنبل (در اولین فراخوانی find ایجاد میشود). Get.putAsync — مقداردهی اولیه ناهمزمان (برای سرویسهای دارای init). Get.delete — حذف از کانتینر (به طور خودکار توسط Bindings هنگام نابودی مسیر فراخوانی میشود).
| متد | زمان ایجاد | زمان حذف |
|---|---|---|
| Get.put | بلافاصله | Get.delete یا onClose |
| Get.lazyPut | در اولین find | Get.delete یا onClose |
| Get.putAsync | پس از اجرای Future | Get.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 بر اساس پوششهای Rx است که از طریق GetStream — پیادهسازی اختصاصی Stream بهینهشده برای Flutter — کار میکنند. بر اساس بنچمارکهای GetX، متغیرهای Rx در بهروزرسانیهای مکرر (۳۰+ فریم در ثانیه) ۲-۳ برابر سریعتر از ChangeNotifier و ۵-۷ برابر سریعتر از BLoC هستند. GetX از BuildContext برای اشتراک استفاده نمیکند که بازسازی درخت ویجت را در هنگام ناوبری حذف میکند.
Best practices: برای ویجتهایی با تعداد زیادی عناصر فرزند (لیستها، جداول) به جای Obx از GetBuilder استفاده کنید. Controllerها را بر اساس ماژولهای عملکردی تقسیم کنید، نه یک Controller عظیم برای کل صفحه. برای مقداردهی اولیه Controller از Bindings استفاده کنید، نه Get.put در متد build. GetView — StatelessWidget کوتاهشده با دسترسی به Controller از طریق controller بدون Get.find.
محدودیتهای شناخته شده: GetX از متغیرهای سراسری (Get.find، Get.to) استفاده میکند که میتواند تست را دشوار کند. mock کردن وابستگیها از طریق GetX نیاز به Get.replace() یا Get.reset() بین تستها دارد. برای ایزوله کردن، Get.testMode = true توصیه میشود. GetX برای برنامههایی که نیاز به معماری سخت با مرزهای لایهای مشخص دارند توصیه نمیشود — در این مورد BLoC یا Riverpod با کدسازی ترجیح داده میشوند.
سوالات متداول
GetX — میکروفریمورک با DI، ناوبری و واکنشگرایی Rx خود. Provider — فقط مدیریت وضعیت از طریق ChangeNotifier و InheritedWidget. GetX نیازی به BuildContext ندارد، دارای ناوبری داخلی و DI است، boilerplate را ۶۰-۷۰٪ کاهش میدهد. Provider از Flutter Navigator استاندارد استفاده میکند و برای DI نیاز به راهحلهای شخص ثالث دارد. GetX در توسعه سریعتر است، Provider — به Flutter API بومی نزدیکتر.
Workers — ابزارهایی برای پردازش واکنشگرای تغییرات متغیرهای Rx. ever — callback برای هر تغییر، once — فقط برای اولین تغییر، debounce — با تأخیر (برای فیلد جستجو)، interval — حداکثر N بار (برای تحلیل). Workers در onInit() GetxController اعلام میشوند و به طور خودکار در onClose() از اشتراک خارج میشوند. این جایگزین addListener/removeListener دستی با ChangeNotifier میشود.
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 برای پروژههای هر اندازهای مناسب است، اما نیاز به انضباط دارد. برای پروژههای بزرگ (۱۰+ صفحه) استفاده کنید: Bindings برای ایزوله کردن Controller، ماژولها (فایلهای GetPages بر اساس قابلیت)، GetView به جای Get.Find دستی در build. ریسک اصلی — سوءاستفاده از دسترسی سراسری (Get.find در هر جایی). بازبینی کد سختگیرانه و راهنماییهای معماری این مشکل را حل میکند. بسیاری از برنامههای تولیدی با میلیونها کاربر روی GetX کار میکنند.
Bindings — کلاسی که مسیر را با وابستگیهای آن مرتبط میکند. هنگام ورود به صفحه، Binding Controller و سرویسها را از طریق Get.lazyPut ایجاد میکند و هنگام خروج آنها را حذف میکند. Bindings مقداردهی اولیه تنبل را پیادهسازی میکنند: Controller تا زمانی که صفحه باز نشده در حافظه وجود ندارد. این باعث صرفهجویی در RAM و زمان راهاندازی برنامه میشود. در GetPage اعلام میشود: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.