State Management In Flutter Using Provider

Flutter State Management Using Provider

My first Flutter project would have been a lot better if I had a solid state management solution implemented for my Flutter app. Choosing the best technology for state management , would have made my life far more easier. So in this article we’ll be taking a look at how to manage state with the Provider framework for our Flutter applications.

Flutter is the hip new child on the street. From a single codebase, you can create native and performant mobile and web apps with Google’s UI kit. Above all, the large number of widgets accessible ensures a quick and entertaining development process.

I was so captivated with Flutter’s potential that I immediately started working on my first Flutter project as soon as the beta release for Flutter got published. Flutter fulfils all of its promises. However, the advantages that a new framework delivers come with some unique challenges as well.

It’s always a good idea to read the official documentation before playing with frameworks. Flutter’s documentation is continuously updated and new articles are added regularly as it has only been around for a few years.

Do You Even Need To Manage Your Flutter App State Using Provider?

Passing state through properties and callbacks can save you a lot of boilerplate code, if your application is designed to be relatively flat and state rarely travels more than one level up or down the widget tree.

The Parent passes a callback to the Child in the example below to keep track of how many times the TextButton is clicked:

class ParentState extends State<Parent> {
  int clicked = 0;

  void updateClickCount() {
    setState(() {
      clicked += 1;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(children: [
        Child(onClickedCallBack: updateClickCount,),
        Text('I was clicked $clicked times!')
      ],)
      
    );
  }
}

class Child extends StatelessWidget {
  const Child({ key, this.onClickedCallBack }) : super(key: key);

  final void Function() onClickedCallBack;

  @override
  Widget build(BuildContext context) {
    return TextButton(onPressed: onClickedCallBack, child: Text('Click me!'))
  }
}Code language: JavaScript (javascript)

However, if you’re sending callbacks across numerous layers of the widget tree, handling state this way gets inefficient and complex rapidly. In this instance, you may be certain that a more powerful method of handling state is required. That is where Provider state management for Flutter comes into play.

Managing State Of Flutter App With Provider

In a Flutter app, you have a lot of choices for managing your state. One of the most popular state managers is Provider. Three basic elements underpin this community-created tool:

  1. ChangeNotifier: your state’s store, from which the state is changed and widgets that consume it are alerted.
  2. ChangeNotifierProvider: This widget allows underlying widgets in the tree to access the ChangeNotifier.
  3. Consumer: a widget that monitors state changes and adjusts the user interface accordingly.

An updated click count utilising the Provider pattern is shown below:

  • The DataProvider class, which stores the _count, stores and manages state.
  • When a button is clicked, the Child widget calls IncrementCount, which updates the _count.
  • NotifyListeners() ensures that the Parent widget, which uses Consumer to retrieve the state, is updated.
class DataProvider extends ChangeNotifier {
  int _count = 0;
  int get count => _count;
 
  DataProvider() {}
 
  void incrementCount(){
    _count++;
    notifyListeners();
  }
}

class Parent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (BuildContext context) { DataProvider();},
      child: Consumer<DataProvider>(
        builder: (context, dataProvider, _) => Container(
          child: Column(children: [
            Child(),
            Text('I was clicked ${dataProvider._count}. times!')
          ],)
          
        ),
      ),
    );
  }
}

class Child extends StatelessWidget {
  const Child({ key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    DataProvider _data = Provider.of<DataProvider>(context);
    return TextButton(onPressed: () => _data.incrementCount(), child: Text('Click me!'))
  }
}Code language: JavaScript (javascript)

Provider State Management is it the ideal state management tool for Flutter apps?

Pros

  • Package is well-maintained and battle-tested.
  • Unidirectional state management toolset in its entirety.

Cons

  • With a whopping nine distinct provider classes, it is difficult to comprehend Provider completely.
  • Unnecessary rebuilds are difficult to prevent. Consumer updates all of its child widgets by default, even if just a small fraction of the state has changed.
  • Because Provider is reliant on the Flutter SDK, your business logic and framework are inextricably linked. In architectural design, this is considered a terrible practice.
  • Events aren’t used to update the state. So, in the above example, we know that _count has been changed, but we can only speculate on the cause of the change. This makes it more difficult to track and comprehend state changes in your apps.

Conclusion

In conclusion, I believe Provider is a fantastic choice for experienced Flutter developers working on a small state app. Provider is simple to learn but difficult to master, and it lacks event-based state monitoring, which is required for more complicated systems.

In this article, we took a look at how to manage state for our Flutter project using the Provider state management framework. As always, If you have found this article useful do not forget to share it and leave a comment if you have any questions. Happy Coding 🙂

Comments

Leave a Reply