Dive into State Management in Flutter

Kunal Kaushik
GDSC, IIIT Allahabad
5 min readJan 14, 2022

In this article we will Dive into State Management ,one of the most confusing and hot topic of Flutter.

Flow of Article:

Basics of State and State Management

Different types of State and Use cases

Different Ways to manage State

Advantages of InheritedWidget

Conclusion

Let’s start with the basics.

What is state?

Across the internet and among developers we find multiple answers which tends to confuse us. Some common answers :

  • The data .
  • All the variables in all the StatefulWidgets.
  • Any variable that changes.

But the definition that makes much more sense is

The behavior of the app at a given moment in time .

What is State Management?

The Flutter framework handles some state, but as we know, Flutter is declarative. That means it rebuilds a UI StatefulWidget from memory when the state or data changes or when another part of your app uses it.

State management is, as the name implies, how you manage the state of your widgets and app.

Why we need State Management?

One thing we should remember is that Flutter is a UI Tool Kit. The main job of a UI is to represent state. Imagine, for example, you have a Recipe App and you’re loading a list of recipes from the network. While the recipes are loading, you show a spinning widget. When the data loads, you swap the spinner with the list of loaded recipes. In this case, you move from a loading to a loaded state. Handling such state changes manually, without following a specific pattern, quickly leads to code that’s difficult to understand, update and maintain. One solution is to adopt a pattern that programmatically establishes how to track changes and how to broadcast details about states to the rest of your app. Here comes the State Management to make our life easy.

Different types of States and Use cases :

Widget State

A stateless widget is drawn with the same state it had when it was created . A stateful widget preserves its state and uses it to (re)draw itself in the future.

Carrying Forward the previous example of Recipe App, suppose you have a Recipes screen which has a card with the list of previous searches and a GridView with a list of recipes:

The left side shows some RecipeList widgets, while the right side shows the state objects that store the information each widget uses. An element tree stores both the widgets themselves and the states of all the stateful widgets in RecipeList:

If the state of a widget updates, the state object also updates and the widget is redrawn with that updated state.

This kind of management handles state only for a specific widget. But what if you want to manage state for your whole app or share state between widgets and screens? You do this using Application State.

Application State

In Flutter, a stateful widget can hold state, which its children can access, and pass data to another screen in its constructor. However, that complicates your code and you have to remember to pass data objects down the tree. Wouldn’t it be great if child widgets could easily access their parent data without having to pass in that data?

There are several different ways to achieve that, both with built-in widgets and with third-party packages. We’ll look at built-in widgets.

Different ways to manage state :

Let’s assume, our app needs to save three things: the list to show in the Recipes screen, the user’s bookmarks and the ingredients. We’ll use state management to save this information so other screens can use it.

StatefulWidget:

StatefulWidget is one of the most basic ways of saving state. The RecipeList widget, for example, saves several fields for later usage, including the current search list and the start and end positions of search results for pagination.

When you create a stateful widget, you call createState(), which stores the state internally in Flutter to reuse when the parent needs to rebuild the widget tree. When the widget is rebuilt, Flutter reuses the existing state.

We use initstate() for one-time work, like initializing text controllers. Then we use setState() to change state, triggering a rebuild of the widget with the new state.

StatefulWidget is great for maintaining internal state, but not for state outside of the widget. One way to achieve an architecture that allows sharing state between widgets is to adopt InheritedWidget.

InheritedWidget:

InheritedWidget is a built-in class that allows its child widgets to access its data. It’s the basis for a lot of other state management widgets. If you create a class that extends InheritedWidget and give it some data, any child widget can access that data by calling

 context.dependOnInheritedWidgetOfExactType<class>(). 

Wow, that’s quite a mouthful! As shown below, <class> represents the name of the class extending InheritedWidget.

class RecipeWidget extends InheritedWidget {final Recipe recipe;RecipeWidget(Key? key, required this.recipe, required Widget child}) :super(key: key, child: child);@overridebool updateShouldNotify(RecipeWidget oldWidget) => recipe != oldWidget.recipe;static RecipeWidget of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<RecipeWidget>()!;}

We can then extract data from that widget. Since that’s such a long method name to call, the convention is to create an of() method.

Then a child widget, like the text field that displays the recipe title, can just use:

RecipeWidget recipeWidget = RecipeWidget.of(context);print(recipeWidget.recipe.label);

StreamBuilderWidget:

StreamBuilder is a widget that you can place in your widget tree that rebuilds itself every time an object is received in a stream.

To understand it better, I have created an in-depth article on StreamBuilder which you can refer:

Advantages and Disadvantages of InheritedWidget

An advantage of using InheritedWidget is it’s a built-in widget so you don’t need to worry about using external packages.

A disadvantage of using InheritedWidget is that the value of a recipe can’t change unless you rebuild the whole widget tree because InheritedWidget is immutable. So, if you want to change the displayed recipe title, we’ll have to rebuild the whole RecipeWidget.

Conclusion:

In this article, we tried to have a better understanding and clarity about State Management in Flutter . We learnt the concepts using an example of Recipe App making it easier for you to apply in your app. I would really appreciate it if you explore more around State Management and its various third-party packages or solutions.

--

--