📜 ⬆️ ⬇️

Manage application state in Flutter

Hi, Habr! I submit a translation of the article, let me help you understand and choose a state management solution for your app that interested me in the process of learning the basics of state management in Flutter. I will be glad to hear any criticism regarding this translation. In the return quotes (``) my personal thoughts and explanations will be written.


Flutter status management is a hot topic. There are many possible solutions to the problem and getting lost in them, choosing the most suitable one for your needs is extremely simple. I myself was confused, but I found the right solution. Let me share it with you.

To find a solution that fits your needs, you need to determine your own needs. In my case it is:


Given these requirements, suitable options remain:
')

Difference between local and global state


Before diving into the analysis of selected solutions, it is necessary to understand the difference between the local and global state. A practical example is suitable for this:
Imagine an authorization form, where the user is prompted to enter a username and password and get the object "user identity" after submitting the form. In this example, any verification of the data entered in the form fields will be part of the local state of the 'authorization form widget`, and the rest of the application should not be aware of this. And the “personality” object returned by the `authorization server` is a part of the global state. So how other components depend on this object that change the behavior depending on whether the user is authorized.

Brief conclusions for those who are tired of waiting
If you do not want to wait, or are not interested in my research, here is a brief overview of the results:


My recommendation is to use BLoC to manage the local state and Redux for the global state, especially if you are creating a complex application that will grow with time.


Why you should not use setState ()


Using setState() inside your widgets is great for quickly creating prototypes and getting feedback on these changes, but this way does not help us achieve our goals, because the display logic is mixed with business logic, which violates the principle of purity and quality of the code. Maintenance of this code will be difficult in the future, therefore, except for prototyping, this approach is not recommended.

ScopedModel - step in the right direction


ScopedModel is a third-party library by Brian Egan . It allows you to create special Models objects, as well as use the notifyListeners() method when necessary. For example, to track on any change in the property of a model object:

 class CounterModel extends Model { int _counter = 0; int get counter = _counter; void increment() { _counter++; notifyListeners(); } } 

In our widgets, we will be able to respond to changes in the model using the ScopedModelDescendant widget `provided by this ScopedModelDescendant :

 class CounterApp extends StatelessWidget { @override Widget build(BuildContext context) { return new ScopedModel<CounterModel>( model: new CounterModel(), child: new Column(children: [ new ScopedModelDescendant<CounterModel>( builder: (context, child, model) => new Text('${model.counter}'), ), new Text(" ,     CounterModel") ]) ); } } 

In contrast to the use of the setState() approach, this solution allows us to separate the display logic from the business logic. However, it imposes certain restrictions:


Considering all this, if the state of your application is not easy to manage - I do not recommend using the data approach. I just do not believe that he is capable of productively ensuring the growth and complexity of applications.

Powerful Solution - BLoC


This pattern was coined by Google and used in the same place. He will help us achieve the following goals:


The idea of ​​this approach is very simple:


Google has good examples of using this condition management pattern, because it is widely used and highly recommended by the company.

I myself highly recommend using this approach to manage the local state, but it is suitable even for managing the global state. However, in the latter case, you will encounter a problem - where and how to implement BLoC correctly, so that different components can access it, and Redux comes on the scene.

Redux and BLoC - the perfect mix for me


One of the goals that I described at the beginning of the article was to search for something widely used and predictable, and this Redux is a pattern and a set of tools that together help us manage the global state. It has three basic principles at its core:

The only source of truth is that the entire ` state your application is stored in a tree object in the only store ` store



Link to the original post where the image is taken

This approach to state management is widely accepted by web developers, and its appearance on mobile devices will help to get the benefits of web and mobile-application developers.

Brian Egan is developing both the original Redux and flutter_redux , and he also created a terrific Todo application , in which he applied many architectural patterns, including Redux.
Considering all the qualities of Redux, I strongly advise using it to manage the global state, but you must be sure that you do not use it to manage the local state if you want to scale your application.

Last words


This article is not completely correct or incorrect decision. To decide on what approach to use in your project, you need to determine your needs. For me and my goals, the combination of Redux and BLoC allows my projects to grow quickly and safely, and also facilitates the entry of third-party developers into these projects, thanks to accessible and understandable tools. However, not everyone has the same needs and over time, you can find both problems in the current tools and even better solutions. It is very important to always remain curious, learn and think about whether this or that tool suits you.

Source: https://habr.com/ru/post/435780/


All Articles