flutter_store — Simple state management for Flutter

Olenin Slava
5 min readJun 18, 2019

One and a half years ago Google turned Flutter to an officially production-ready technology by releasing version 1.0. So, even though they started to build it quite a while ago, for the community Flutter is young like a baby. And now it is actually going through many growing up phases very similar to those ReactJS had to face to.

And one of those phases is to find the widely accepted state management system which will be:

  1. Flutter-friendly
  2. Simple to learn and use
  3. Clean and elegant to read

While I worked on a few Flutter-based projects I tried few of the followings and I also will mention redux which I am not the biggest fan of since the moment I switched to MobX for the React-based development. And of course, everything below is purely my opinion and you do not have to agree with me.

StatefulWidget with InheritedWidget

StatefulWidget can be used without any additional libraries if your widgets tree is not deep enough so you can pass all your data through every node. But if your application is bigger than the “counter” app from google examples, very quickly, you will want to be able to access your data without passing them throw every note in the tree. Here, the InheritedWidget can help, but it is just too low level to use it directly. Just too much boilerplate. It is like early versions of the react’s context, which required quite a lot of boilerplate to use it directly but end up being the most common underlying tool for widely accepted systems like Redux and MobX.

2. Redux

Heh, here would be simple. I do not like it, because of two reasons:

  1. Too opinionated, which mean, the whole business logic design is running around this big store, actions, reducers, etc.
  2. Too much boilerplate and the whole ecosystem of plugins built to reduce it or to optimize interactions with the store. It is like creating the technology and spend years to build an ecosystem around, the whole point of which is to fix it.
  3. Since the dart is not as flexible as JavaScript, Redux implementation for the Flutter, of course, in my opinion, definitely does not take the prize for readability!

Super popular, at least in react community! But not for me…

3. MobX

For my react-based projects, the MobX is always my default choice. React + MobX + TypeScript is like a perfect marriage… of three. It gives pretty much full front-end stack, the whole ecosystem like the one mobile developer have with all iOS or Android tools.
Unfortunately, for Flutter, it loses some of its charm.
The main problem is that developer cannot use decorators like in JavaScript to generate getters and setters at runtime, so you either start filling your source code with “Observables” or with boilerplate around them.
The third option would be to use code generation for Flutter with a bit of boilerplate around it. And I do not like it either… do not ask why. Just do not like…

4. BLoC

BLoC is not a specific framework for state management but rather set of conventions in how you suppose to write your business logic where the cornerstone of everything are streams. Basically, you should use streams for all data in your application. You push all changes to the stream and your components should listen to those changes with the help of StreamBuilders. And though, this approach is very friendly to dart and Flutter since dart relies on streams from the very beginning, it also has some problems:

  1. Quite a bit of boilerplate on the business logic side. In your store, you cannot just set a simple value. If you want to be consistent, everything should be a stream. Wanna set the user’s first and last name, turn both of them into a stream or make User object immutable (which make sense of course) and add to the stream a new User, every time one of his properties has changed.
  2. Quite a bit of boilerplate in your widgets. Since now, everything is a stream, you need to use StreamBuilders to listen to any of your data. Imagine, you have a Trello card. You will listen to you Trello entries stream, but entry also has few tags which are common to all your cards so you also listen to tags list. Plus, your card also has a bunch of comments and other data that might be part of the card or referenced by card which means you will also need streams for those references.
  3. I personally really like everything about “Rx” and for both, Android and iOS it is a real saver, but at least in Tokyo, I met a surprisingly small amount of people in mobile, who understand and use it and almost zero people in WEB. No wonder so many developers struggling to adopt the BLoC while it is just “counter” examples. Finding good Flutter developer already a challenge, and adding RxDart to requirement does not make this task easier. ReactiveX is already like a standard with implementations for all popular languages, but Google still put a lot of efforts explaining what the RxDart is.
  4. If you are coming from the ReactJS background, I am sure you would agree, that Flutter is way behind in terms of source code readability. And all those stream builders here and there or many of them in one place, does not make the source any prettier.

Yet, In my opinion, out of the three I mentioned above, the BLoC has the biggest chances to be widely adopted, while I also think the best solution is still yet to be found.

Alternatives?

Let’s take “our favorite counter” example and try to make the counter store in the most simplistic way:

So far, I think, everything should make sense:

  1. We should not be able to modify the value outside of Counter instance, so we made it private
  2. We still, need to be able to access it, so we made a getter.
  3. We need to increment value somehow, so we added the increment method.

Now, we need to notify our components when our value will be changed. With Stateful Widget, we just need to use “setState” method when any state needs to be changed.

And this is where flutter_store come into place. It works just like StatefulWidget but does not have to be inside of the Widgets tree. It also has the Provider widget to pass the store down the tree.

Let’s finish our Counter example with flutter_store used for the state management.

This is it!

The whole point of this is an attempt to find a simple solution for state management. It is not opinionated, so for example, nothing stopping you from storing streams in it and using provider to pass those streams down the widgets tree… but in that case, you probably wanna use the Provider package instead.

PS. It also has an “experimental” caching feature which you might wanna try.

UPDATE 1: After reading reader’s comments, reviewed the Provider’s examples, I found out that they added the same functionality with ChangeNotifier mixing except minor cosmetic differences.

--

--

Olenin Slava

Passionate Software Developer with a strong focus on Web, 3D, Mobile, and pretty much any interactive computer graphics.