GetX State Management Flutter Tutorial

In this blog, we will explore the features of getx package. So let’s get started.

Introduction to GetX State Management

GetX is the most powerful, extra lightweight, high-performance framework for building flutter apps. It is the combination of state management, dependency injection, and route management. There are many state management libraries are available in the flutter like MobX, BLoC, Redux, Provider, etc. But, Getx has a simple syntax and anyone easy to use. In addition, it reduces the many boilerplate codes. We don’t need context for creating snack bars, dialogs, and bottom sheets and we don’t need StreamControllers and StreamBuilders.

Principles of GetX

The Getx has 3 principles. There are,

  • Performance
  • Productivity
  • Organization

Features of GetX

  • Easy Navigation
  • Snack bars, dialogs, and bottom sheets with no contexts
  • Easy state management
  • Easy dependency injection
  • Easy key/value storage
  • Easy change theme
  • Easy Validators
  • Easy internationalization

Installing GetX

To install the getx of visit the GetX official page on pub.dev and copy the latest version of the package. Then  Open pubspec.yaml file and add getx package in your dependency. Then don’t forget to run pub get, then only the package will add your project. 

dependencies: get: ^4.1.4
Code language: CSS (css)

As of the time of writing this article, the current version of GetX is 4.1.4. It may change in feature. Please use the latest version. 

Alternatively, you can run the flutter pub add get command.

flutter pub add get
Code language: JavaScript (javascript)

Now, import the package of your project.

import 'package:get/get.dart';
Code language: JavaScript (javascript)

Then, Instead of using MaterialApp change it into the GetMaterialApp, Example Code given below,

class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(), ); } }
Code language: JavaScript (javascript)

Getting Started With GetX

Now, we explore the features of getx one by one.

Route Management

In the old method, we use Navigator. Now we don’t need any lengthy code.

Navigation without named routes

Navigate to a new screen:

Get.to(NextScreen());
Code language: CSS (css)

To close snack bars, dialogs, bottom sheets, 

Get.back();
Code language: CSS (css)

This method is used to go to the next screen and remove the previous screen. This method is helpful when we use SplashScreens, login screens and etc.

Get.off(NextScreen());
Code language: CSS (css)

This method is used to go to the next screen and remove all previous routes. This method is useful when we use shopping carts, polls, and tests, etc.

Get.offAll(NextScreen());
Code language: CSS (css)

Navigation with named routes

If you prefer navigation with named routes you can these methods. Initially, we need to define the routes,

void main() { runApp( GetMaterialApp( initialRoute: '/', getPages: [ GetPage(name: '/', page: () => MyHomePage()), GetPage(name: '/second', page: () => Second()), GetPage( name: '/third', page: () => Third(), transition: Transition.zoom ), ], ) ); }
Code language: JavaScript (javascript)

Navigate to a new screen with a name.

Get.toNamed('/details');
Code language: JavaScript (javascript)

This method is used to go to the next screen and remove the previous screen. This method is helpful when we use SplashScreens, login screens and etc.

Get.offNamed("/NextScreen");
Code language: JavaScript (javascript)

This method is used to go to the next screen and remove all previous routes. This method is useful when we use shopping carts, polls, and tests, etc.

Get.offAllNamed("/NextScreen");
Code language: JavaScript (javascript)

If any route is missed, that makes a 404 error. To handle the non-defined routes, we can use the unknown route.

void main() { runApp( GetMaterialApp( unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()), initialRoute: '/', getPages: [ GetPage(name: '/', page: () => MyHomePage()), GetPage(name: '/second', page: () => Second()), ], ) ); }
Code language: JavaScript (javascript)

Navigation without context

In getx, we don’t need any context for creating snack bars, dialogs, and bottom sheets.

SnackBars

Get.snackbar('Hi', 'i am a modern snackbar');
Code language: JavaScript (javascript)

Dialogs

Get.dialog(YourDialogWidget());
Code language: CSS (css)

BottomSheets

Get.bottomSheet( Container( child: Wrap( children: <Widget>[ ListTile( leading: Icon(Icons.music_note), title: Text('Music'), onTap: () {} ), ListTile( leading: Icon(Icons.videocam), title: Text('Video'), onTap: () {}, ), ], ), ) );
Code language: PHP (php)

State Management

Getx has two different state managers. They are,

  1. Simple State Manager (GetBuilder)
  2. Reactive state manager (GetX/Obx)

Simple State Manager (GetBuilder)

In Simple State Manager, it updates only the required widgets and the state manager uses less memory(~ 0MB). It does not need a change notifier.

First, create a controller class and extends GetxController. Then write your method/function and use update() to update the counter variable on UI.

class Controller extends GetxController { int counter = 0; void increment() { counter++; update(); } }
Code language: JavaScript (javascript)

In Getx, you don’t need a stateful widget. Wrap your existing widget as GetBuilder and give the Controller a parameter. Then initialize the controller using the init property. In the builder property, give your widget. The sample code is given below,

GetBuilder<Controller>( init: Controller(), // INIT IT ONLY THE FIRST TIME builder: (_) => Text( '${_.counter}', ), )
Code language: JavaScript (javascript)

Note: Initialize the controller only one time. Don’t initialize the same controller in another place. In second-time use ReBuilder for the same controller.

Reactive state manager (GetX/Obx)

In Reactive State Manager you don’t need any StreamControllers, StreamBuilders, and other stuff.

Simply create a variable,

var name = 'Shibu';
Code language: JavaScript (javascript)

Make it observable. To make it observable, simply add the “.obs” end of it.

var name = 'Shibu'.obs;
Code language: JavaScript (javascript)

Update the variable as per your need,

name.value='Code With Flutter';
Code language: JavaScript (javascript)

To update the UI as dynamic, wrap your existing widget as Obx. Example code is given below,

Obx(() => Text("${controller.name}"));
Code language: JavaScript (javascript)

That’s all. It’s that simple.

For Example of Reactive State Manager,

class Controller extends GetxController{ var count = 0.obs; increment() => count++; }
Code language: PHP (php)
class Home extends StatelessWidget { @override Widget build(context) { final Controller c = Get.put(Controller()); return Scaffold( appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))), body: Center(child: ElevatedButton( child: Text("Go to Other"), onPressed: () => Get.to(Other()))), floatingActionButton: FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment)); } } class Other extends StatelessWidget { final Controller c = Get.find(); @override Widget build(context){ return Scaffold(body: Center(child: Text("${c.count}"))); } }
Code language: JavaScript (javascript)

Dependency Management

One of the main features of Getx is simple and powerful dependency management. So we don’t need Provider context and inheritedWidget.

Instancing methods

To implement the dependency injection, there are four types of methods are available.

  1. Get.put()
  2. Get.lazyPut
  3. Get.putAsync
  4. Get.create
Get.put()

The Get.put() method is the most common way of injecting dependency. For Example,

Controller controller = Get.put(Controller());

To keep the dependency as an entire session, you can add the permanent property as true. For Example,

Get.put<LoginController>(LoginController(), permanent: true);
Code language: HTML, XML (xml)
Get.lazyPut

 It will be instantiated only when is used. For Example,

Get.lazyPut<Controller>(() => Controller());
Code language: JavaScript (javascript)
Get.putAsync

If you want to use an asynchronous instance, you can use Get.putAsync.

Get.putAsync<YourAsyncClass>( () async => await YourAsyncClass() );
Code language: JavaScript (javascript)
Get.create

It creates a new instance of the dependency every time Get.find is called.

Get.Create<SomeClass>(() => SomeClass()); Get.Create<LoginController>(() => LoginController());
Code language: JavaScript (javascript)

Using instantiated methods/classes

To use the injected dependency in another class, you can use Get.find() method. For Example,

final controller = Get.find<Controller>(); // OR Controller controller = Get.find();
Code language: PHP (php)

For more information about getx visit official documentation.