Ever since it was released, Google’s Flutter has been one of the most hyped cross-platform software development kits for developing mobile apps. It challenges Facebook’s React Native in almost all areas. Despite being a relative newcomer, Flutter has confirmed its place as a potential programming framework in a modern mobile development toolkit. The original version of Flutter was released in May 2017.
I have an extensive background in programming, and I specialize in mobile app development, so testing out Flutter has been on my mind for a while now. I decided to approach Flutter through state management, as this is one of the most important areas of developing more complex applications, and it gives an idea of the tool’s diversity.
Flutter in brief
Flutter appears to be a surprisingly mature and well-thought-out programming framework. It comes with a number of useful additional tools that make an app developer’s day easier. I consider fast code updating on the device most important, which, in the best-case scenario, can even be done without resetting the application’s state. This means it is possible to change a button’s function during execution and to test it immediately without the need for a long compilation process or restarting the app. Another useful function is Flutter Doctor, which helps identify problems in the installation and operation of Flutter and other critical dependencies. Another bonus is the automatic code formatting at the click of a button.
In order to gain some insight into Flutter, I decided to develop a rather simple app that nevertheless uses state management in at least two places. I created a shopping list app, where you can add things to the list and either delete the entire list or parts of it. I developed the app’s state management three times: first, Flutter’s default state management on StatefulWidget, then on React’s well-known Redux, and finally on the Provider library.
StatefulWidget is Flutter’s default state management. It is straightforward and user friendly on small apps or unique app parts that do not need to interact with other parts. This solution may, however, cause state management problems in broader apps where the aim is to use the same state in more than one place, as the state is saved in the UI components themselves. Problems may arise, for instance, in an online shopping app’s shopping cart status, whose data can be used in several places in various parts of the app. In my example app, even this worked rather well, however, and it took just a bit more than an hour to develop the app itself.
Redux, familiar especially from the React world, is also available for Flutter in two versions: Async_redux and Flutter_redux. The former advertises itself as being easier to use and requiring less extraneous definition code than Flutter_redux, which is a more traditional compilation of Redux. In both libraries, however, the main idea is the same: to offer single source of truth state management, in which every change can be traced and is possible only through certain reducer functions.
Redux is an effective tool for apps in which the same state is required in several places, as the state is always up to date everywhere. The initialization of Redux is, however, always a relatively laborious stage, and for this kind of app it is also excessively demanding, without even attaining any actual benefits. This is no surprise, really, as the app is so simple. One interesting aspect is that the flutter_redux_dev_tools library offers good tools for debugging Redux, such as a “time machine,” that can be used to individually browse each state change, and even offers the possibility of jumping back to any previous state.
Provider is originally a separate state management library, but nowadays even Google itself recommends it for developing more versatile apps. Provider applies the Business Lines of Code (BLoC) approach and helps isolate the application’s logic and state from the user interface, offering an interface through which all state changes take place. Provider’s architecture is reminiscent of Redux, as state management is only in one place and interface functions can be created for using it.
Although the initialization of Provider is much less laborious than Redux, it does not offer as limited an environment, which is why it is easier to use incorrectly. Contrary to good manners, it is therefore possible to request state through Provider and manipulate it directly from anywhere, rather than keeping the state immutable and modifying it only through interfaces as in Redux. The situation can be eased, however, through private variables and public getters through which changes cannot be saved in state management from just anywhere. Provider, in fact, proved to be my favorite thanks to being so light, at least in this test app.
After a few days of lightly scratching the surface, I have a surprisingly good general impression of Flutter. Jumping into the unknown proved to be rewarding and delightfully simple. Getting started is very quick and straightforward. The documentation is generally good, and the number of libraries that are available is continuously growing.
I still have a lot to learn, however, before I can say I truly know Flutter, as there are many other important components that require more in-depth study. But this is a good place to start.
The writer is a software developer specializing in mobile apps at Etteplan MORE. The intention was to offer basic information to colleagues who are not yet familiar with Flutter, but since others are no doubt interested in the topic, we decided to share it with everyone.