States of an Application
Explore how to manage application state in Flutter by differentiating ephemeral and app states. Understand common state management solutions including setState, InheritedWidget, Provider, BLoC, and Riverpod to build maintainable and scalable apps.
We'll cover the following...
What is state?
State refers to data that changes during the life cycle of our application. It’s the data your application manipulates, and the user interface (UI) is generated based on the current state of our app.
State objects are persistent between calls to the build() method, allowing them to remember information between UI rebuilds.
Categories of state
We can categorize states in Flutter into two categories:
- Ephemeral state
- App state
Ephemeral state
Ephemeral state, also known as UI state or local state, is the state contained within a single UI widget. Such a state is usually not needed or accessed by other widgets within our application.
Examples of ephemeral states include:
- The currently selected tab in a
BottomNavigationBar - The current state of a checkbox or radio buttons
- The value of a text field within a widget
In the example above, the position of the currently active tab in a bottom navigation bar is held in the _index field of the _MyHomepageState class. In this example, _index is an ephemeral state and, therefore, is only accessible within the _MyHomepageState class.
App state
App state refers to the state that widgets within our application share. We might also want to keep this state between different user sessions.
Examples of app states are:
- User preferences
- Authentication or authorization information
- Notifications in a social networking app
- The shopping cart in an e-commerce app
- Read/unread state of articles in a news app
How to manage state
State management is the approach we take to handling our application’s state. The ephemeral state can be managed using State and setState().
App state, on the other hand, is more complex and can be handled using Flutter’s InheritedWidget or with various state management packages, such as:
- Provider
- Riverpod
- BLoC
In the code snippet above, the brightness of the application is accessible from the mode attribute of the BrightnessMode class. The current value of the mode object is accessible to all descendant widgets of the BrightnessMode widget using the BrightnessMode.of(context) method. In this example, the mode object is an app state since it is accessible from other widgets within the application.
Choosing the state management option
You might want to research to decide which option to use for your app state management. Your decision will depend on the nature and complexity of your application, your team’s (or your own) previous experience, and other aspects of your project.
The following are some of the reasons why effective state management is essential:
- We can easily share the state across our application.
- Developers can add more features to their applications without breaking them.
- The UI of our application is kept separate from the business logic.
- The app remains testable.
In this chapter, we’ll manage the state of the TODO app below using the following state management techniques:
- Flutter’s
setStatemethod - Flutter’s
InheritedWidgetclass - The
providerpackage - Business Logic Components (BLoC)
- Dependency injection
- The
riverpodpackage