Mastering State Management in Flutter with GetX: Tips and Tricks for Developers



Hello Flutterwithpraveen readers. Today we are going to discuss about Getx in Flutter.GetX is an extra-light and powerful solution for Flutter. It combines high-performance state management, intelligent dependency injection, and route management quickly and practically.

There are so many State Management libraries in flutter like MobX, BLoC, Redux, Provider, etc.

GetX, a state management solution for Flutter, offers a variety of benefits, such as:

Simplicity: GetX makes handling state in Flutter easy. It has a simple and easy-to-understand way of writing code, which means less extra code and makes it easier to read and maintain your app.

Performance: GetX is built to work fast. It keeps your app running smoothly, even as it gets more complicated.

Reactive: GetX automatically updates your app's look whenever something changes, so you don't have to do it manually.

Dependency Injection: GetX helps you keep track of all the different pieces of your app and makes sure they work well together.

Navigation Management: GetX helps you move around your app smoothly and keeps track of where you are.

Internationalization (i18n): GetX helps you translate your app into different languages, so people all over the world can use it.

State Persistence: GetX helps your app remember things even when you close it and open it again.

Integration: GetX works nicely with other tools you might want to use, so you can add extra features easily.

Productivity: GetX aims to maximize developer productivity by providing a concise and intuitive API, reducing the amount of code needed to accomplish tasks, and streamlining common development workflows. It emphasizes simplicity and efficiency to accelerate the app development process.

Performance: GetX prioritizes performance, ensuring that Flutter apps built with GetX are fast and responsive. It optimizes resource usage and minimizes overhead to deliver a smooth user experience, even as the complexity of the app grows.

Organization: GetX promotes a modular and organized code structure. It encourages separation of concerns, facilitates code reuse through dependency injection, and offers tools for efficient state management and navigation. By promoting a clean and organized codebase, GetX enhances code maintainability and scalability.

    GetX Managements:

    State Management: There are two types of state management:
    • Simple State Manager: It uses GetBuilder.
    • Reactive State Manager: It uses GetX and Obx

     

    • Route Management: If we want to make Widgets like Snackbar, Bottomsheets, dialogs, etc. Then we can use GetX for it because GetX can build these widgets without using context.
    • Dependency Management: If we want to fetch data from other Class then with the help of GetX, we can do this in just a single line of code. Eg: Get.put()


    Reactive State Manager: reactive state management, we work with observables(a data stream) and observers(the components that listen to changes in data).


    Sure, here's a simplified version:

    "GetXController: 

    Before diving deep, let's understand a concept called Controller. In an app, the logic that controls how things work is stored inside a controller. GetX introduces a special class known as GetXController. This class offers three methods that you can customize:

    1. **onInit()**: This method is triggered when the controller is created.
       
    2. **onReady()**: It's called after the widget is displayed on the screen.
       
    3. **onClose()**: This method is invoked when the controller is removed from memory.

    Using GetXController reduces the need for a stateful widget. You can set up data in onInit() or onReady(), and clean up resources in onClose(). This simplifies app development by separating business logic from UI components."


    class MyController extends GetxController{

      @override
      void onInit(){
        // Get called when controller is created
        super.onInit();
      }

      @override
      void onReady(){
        // Get called after widget is rendered on the screen
        super.onReady();
      }

      @override
      void onClose(){
        //Get called when controller is removed from memory
        super.onClose();
      }
    }


    Creating observables:

    here are the three ways to make a variable observable in GetX:

    a . The first is using Rx{Type}.

    // initial value is recommended, but not mandatory
    final name = RxString('');
    final isLogged = RxBool(false);
    final count = RxInt(0);
    final balance = RxDouble(0.0);
    final items = RxList<String>([]);
    final myMap = RxMap<String, int>({});

    b . The second is to use Rx and use Darts Generics, Rx<Type>

    final name = Rx<String>('');
    final isLogged = Rx<Bool>(false);
    final count = Rx<Int>(0);
    final balance = Rx<Double>(0.0);
    final number = Rx<Num>(0)
    final items = Rx<List<String>>([]);
    final myMap = Rx<Map<String, int>>({});
    // Custom classes — it can be any class,
    final user = Rx<User>();
    c . The third, more practical, easier and preferred approach, just add .obs as a property of your value :

    final name = ''.obs;
    final isLogged = false.obs;
    final count = 0.obs;
    final balance = 0.0.obs;
    final number = 0.obs;
    final items = <String>[].obs;
    final myMap = <String, int>{}.obs;
    // Custom classes — it can be any class,
    final user = User().obs;



    There are the three main ways to instantiate controllers in GetX:

  • Using Get.put().
  • Using Get.find().
  • Using Get.lazyPut().


  • import 'package:flutter/material.dart';
    import 'package:get/get.dart';

    void main() {
      runApp(MyApp());
    }

    class CountController extends GetxController {
      // Define a reactive variable
      var count = 0.obs;

      // Function to increment the count
      void increment() {
        count.value++;
      }
    }

    class MyApp extends StatelessWidget {
      // Instantiate the controller
      final CountController controller = Get.put(CountController());

      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Reactive State Management Example'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  // Observe the 'count' variable and rebuild the Text widget whenever it changes
                  Obx(() => Text(
                        'Count: ${controller.count.value}',
                        style: TextStyle(fontSize: 24),
                      )),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      // Call the increment function when the button is pressed
                      controller.increment();
                    },
                    child: Text('Increment'),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }


    Let’s see simple state management with GetX

    In simple state management we don’t have to work with observables but we need to work with normal variables.



    import 'package:flutter/material.dart';
    import 'package:get/get.dart';

    void main() {
      runApp(MyApp());
    }

    class CounterController extends GetxController {
      var count = 0;

      void increment() {
        count++;
        update(); // Manually trigger UI update
      }

      void decrement() {
        count--;
        update(); // Manually trigger UI update
      }
    }

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

      @override
      Widget build(BuildContext context) {
        return GetMaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Simple State Management with GetX'),
            ),
            body: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  GetBuilder<CounterController>(
                    builder: (controller) => Text(
                      'Count: ${controller.count}',
                      style: TextStyle(fontSize: 24),
                    ),
                  ),
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () {
                      controller.increment();
                    },
                    child: Text('Increment'),
                  ),
                  SizedBox(height: 10),
                  ElevatedButton(
                    onPressed: () {
                      controller.decrement();
                    },
                    child: Text('Decrement'),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }

    Thank You!














     



    Comments

    Popular posts from this blog

    Unlocking the Power of OOP: A Beginner's Guide to Objects, Encapsulation, Inheritance, Abstraction, and Polymorphism

    HTTP GET Response in Flutter

    Building a Flutter Firebase Firestore CRUD App