GetX: Flutter State Managment

Clarity

State management is undoubtedly the most discussed topic within the Flutter community, and no wonder. The choice has a determining factor in the development and maintainability of the code.
There are many options and each of them has its advantages and disadvantages, that is why there is, to this day, no consensus on which is the best of all these options.
Today I want to show you GetX. This package was a nice discovery for me and, after using it, it has become my first choice in state management. I invite you to try it and see for yourself the benefits it brings.

What is GetX?

GetX is a micro-Framework for Flutter that allows us, among many other things, to manage the state in a simple way by taking the logic out of our widgets.

It is more than a state manager, it offers us a whole ecosystem within which we can manage navigation, internationalization, storage, http or websockets communication and a few other things.

With GetX, all this is done intuitively and easily, without the need to write long lines of code. It allows, for example, to open a Snackbar or a dialogue without using the BuildContext.

Get.snackbar('Title', 'Message');

One thing you should know is that GetX is currently the most liked package of all, so I encourage you to try it out and see why it is.

In this article we are only going to look at State management, but if you are curious about what you can do with GetX, you can take a look at the documentation and you will see why it is so popular.

Working with GetX

In a nutshell, we create controllers that handle the state and we use widgets provided by GetX to wrap our widgets and, through the controllers, update the view.

Controllers

To create a controller we just need to define a class that extends of GetxController. This allows us to override some methods that manage the controller’s lifecycle and state update.
In that class we will write all the logic we need to modify the widgets.

import 'package:get/get.dart';class HomeController extends GetxController {

@override
void onInit() {
super.onInit();
}
@override
void onClose() {
super.onClose();
}
someFunction() {
// Do something
}
}

Put and Find: Injection of the controller into the view

Dependency Injection is another great tool offered by GetX, which could be the subject of another article.
For now, we just need to know how these two methods work to inject controllers into widgets.
The put method adds the controller we pass as an argument to the Get instance, making it accessible to the whole application. This method returns the controller ready to be used.

HomeController _controller = Get.put(HomeController());

The find method searches for a controller that we have previously added with the put method. That way we don’t have to add it every time we want to use it.

HomeController _controller = Get.find<HomeController>();

The way to work would be to add the controller the first time (put) and in the other screens, or in child widgets where we want to use it, we recuperate it from the dependencies (find).

GetX Widgets

GetX offers widgets ready to communicate with the controllers and manage the state for us. There are four widgets we can use: GetBuilder, Obx, GetX and MixinBuilder.
Actually, what these widgets do behind the scenes is to inherit from StatefulWidget and handle state efficiently. The difference between them is based on the type of data they handle (reactive/non-reactive) and the performance they offer.

To keep the article short, we will only look at Obx and GetBuilder as they are the most common ones. In the GetX repository you can find more information on how to work with the rest of them.

Goodbye StatefulWidgets

Yes, you read that right. With GetX we won’t have to use StatefulWidgets, all widgets will be StatelessWidgets, we won’t need to manage the state from the widget, as the controller will take care of it.

Obx

This widget works with reactive data. The nice thing about Obx is that the data is automatically updated in the views when we change its value in the controller. Its syntax is really simple. We just have to wrap the widgets whose state will be managed by the controller:

Obx(()=> // Widgets)

One thing you should know is that, to work with Obx, we have to use reactive variables, but don’t worry, it’s very easy thanks to GetX. The package offers several ways to convert variables to reactive form: we can use types, or just add .obs after their value.
For example, let’s convert the variable var number=0;to reactive form:

var number = 0.obs;
RxInt number = RxInt(0);
Rx<int> number = 0.obs;

As in this example, we have at our disposal types for any primitive data and even for lists and objects: RxString, RxBool, RxList, Rx<MyObject>
These variables will now have a value and an update method to modify that value. When this happens, GetX will rebuild the view for us.

Obx example

First of all, we create a new flutter project and add GetX to the dependencies:

dependencies:
get: ^4.3.8

Now let’s create a controller with some reactive variables and some functions that update those variables.

For didactic reasons, I have included a User class at the end of the controller file so that we can see how it would be done with an Object.

If we look at the methods, primitive data variables are updated by directly changing their value. On the other hand, to modify a property of the object, we use the update method of the reactive variable, as seen in updateUser().

In the view, the first thing we do is inject the controller with the put method and, at the same time, we store it in the _homeController variable. This controller variable is the one we will use to pass data and update functions to the text widgets and button callbacks.

The widgets are wrapped in Obx, which is what allows us to update their values without us having to worry about anything.

GetBuilder

This widget offers simple state management. Unlike Obx, it does not work with reactive data, so we will have to call the update method in the controller every time we want to modify the state of the widget and it will be an update of all the variables that are handled in the GetBuilder state.

This is what the above example would look like with GetBuilder:

GetBuilder example

In the controller, the only difference is the update method at the end of each function to trigger change detection.

In the view we wrap widgets in GetBuilder, which receives the type of Controller that will handle it.

child: GetBuilder<HomeController>

In the init property we invoke the controller’s class, which initialises it and stores it in the dependencies, similar to the put method.
The builder property, gives us the instance of the controller, in it we return the widgets.

Conclusion

So far we would have an introduction to this fabulous package in terms of state management. It is true that there are still many details to be seen, but I don’t think that is the aim of this article, rather it is a first approach to GetX to help us get started with it.

Perhaps at first the particular way of working with GetX is not too comfortable, but as we get deeper into the Get ecosystem, we begin to understand the scope of its benefits. I encourage you to try it out on a project of your own, you won’t be disappointed.

I hope this article has given you something useful. ✌️

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store