Provider - A State Management Solution


In this tutorial I’ll use one of the most popular state management solutions in Flutter, the Provider package. It’s a wrapper around InheritedWidget and provides a straightforward approach on handling state, capable of simplifying and speeding up development.

There are other extremely useful state management packages, such as Flutter Bloc and Mobx that use Provider.

The goal for this tutorial is to cover the package basic usage by implementing a simple use case. For the upcoming tutorials I’ll dive deep into some other package features such as Selectors and ChangeNotifiers.


Final Result

The sample application downloads random images from Unsplash.


For this tutorial I’ll implement a save (bookmark) feature that allows users to save posts from the Post List View (InfiniteList) used in previous tutorials. Saved posts are displayed using a Flutter GridView widget.

I’ll create the HomePage, a Scaffold to host the InfiniteList widget; the SavedPostsPage, a Scaffold wrapping a GridView to display saved posts, and a Drawer widget to navigate between these two pages using Navigator. A Scaffold is a top level container for an application styled with Material Design in mind (CupertinoPageScaffold for a Cupertino styled app). It occupies the entire screen, and has an app bar, a drawer and a body.

I’ll start by adding a property to the Post class to identify each individual post, an uuid. UUIDs can be generated using the uuid package. Every post created using the fake() factory constructor will have a UUID.


Implement the PostsProvider

The PostProvider stores a list of saved posts.


Inject the Provider

The Provider is injected on top of the MaterialApp widget making it accessible across all branches of the app. Since this is a fairly small application that has only two pages and both require access to the provided data, it’s easier to inject the PostsProvider on top of the Navigator, instead of passing it around between branches every time the SavedPostsPage route is pushed.

It’s essential to be aware that when pushing a new route with Navigator.of(context).push(...) a new branch is created, from the Navigator, that can not access widgets that belong to other branches. The Navigator itself is a widget created by the MaterialApp and lies above the home widget.


Accessing the Provider to save a Post

By tapping on the bookmark icon, through PostWidget, the post is saved on the Posts Provider class. It gets the provider using context.read<PostsProvider>() method with a specific template parameter. The template param tells the framework to search for a provider with that same exact type. If there’s more than one provider with the same type, the nearest one is returned.


Using Consumer

The Consumer widget from the Provider Package is used to subscribe to changes and acquire data from a Provider. It also requires a template parameter to be aware of the Provider it should return. Every time the widget is built, it displays the most updated version of the post saved list.



See also