Exploring the Power of Provider for State Management in Flutter

provider flutter

Written and reviewed by: 

SHARE

Hey there, fellow Flutter enthusiasts!  Tighten up your seat belt. Today, we are going to dive into the magical world of state management in Flutter. Let’s unravel the mysteries of the provider package—a state management solution so powerful, it might just make your coffee taste better and your code cleaner. Buckle up, because we’re in for a wild ride through the enchanted forest of Flutter state management.

Table of Contents

What is State management, Anyway?

 

Before we summon the mighty provider, let’s talk about what state management is. Imagine you’re building an app (maybe a to-do list app, because we all love reinventing the wheel). Your app has widgets, and these widgets have states. One moment, your checkbox is unchecked; the next, it’s checked. The state is how your app knows what’s happening right now, and managing this state is like herding cats—it can get out of hand quickly.

Meet the Provider: Your New Best Friend

 

Enter the provider, Flutter’s knight in shining armor. Provider is a dependency injection and state management solution that saves us from the chaos of lifting state up, passing down props, and generally losing our minds. It’s like having a personal assistant for your Flutter app who remembers everything for you.

Why use Provider?

  1. Simplicity: It’s straightforward to use, even if your last coding adventure involved taming dinosaurs in JavaScript.
  2. Performance: It ensures your app runs smoothly, without unnecessary rebuilds. Say goodbye to janky animations!
  3. Scalability: Whether you’re building a simple app or a complex beast, Provider scales with you.

Setting Up Provider

 

Alright, let’s get our hands dirty. First, we need to add provider to our pubspec.yaml file. Open up your trusty text editor and add the following line under dependencies:

				
					dependencies:
  flutter:
    sdk: flutter
  provider: ^latest_version

				
			

Now, run flutter pub get to fetch the package. While it’s downloading, take a moment to enjoy a sip of that coffee—because things are about to get interesting.

A Simple Example: The Counter App

 

No Flutter tutorial is complete without the classic counter app. But this time, we’re going to make it fancy with Provider.

First, let’s create a new Flutter project:

				
					flutter create provider_counter
cd provider_counter

				
			

Step 1: Create a Counter Model

 

In lib, create a new file called counter_provider.dart and define a CounterProvider class that extends ChangeNotifier. This is where the magic happens.

				
					import 'package:flutter/material.dart';

class CounterProvider extends ChangeNotifier {
  int count = 0;

  void increment() {
    count++;
    notifyListeners();
  }

  void decreament() {
    count--;
    notifyListeners();
  }
}

				
			

Here, notifyListeners() is like ringing a bell in the kingdom of your app—letting everyone know that the state has changed.

Step 2: Set Up the Provider

 

Next, modify main.dart to use the Provider package. Wrap your MyApp widget with a ChangeNotifierProvider and pass in an instance of Counter.

				
					import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_tutorial/counter_screen.dart';
import 'provider/counter_provider.dart';

void main() {
  runApp(ChangeNotifierProvider(
      create: (context) => CounterProvider(), child: const MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Provider Tutorial',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const CounterScreen(),
    );
  }
}

				
			

Step 3: Build the UI

Now, let’s build a simple UI for our counter. Create a new file counter_screen.dart and set up a basic layout.

				
					import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_tutorial/provider/counter_provider.dart';

class CounterScreen extends StatelessWidget {
  const CounterScreen({super.key});

  @override
  Widget build(BuildContext context) {
    final counter = Provider.of<CounterProvider>(context);
    return Scaffold(
        appBar: AppBar(
          title: const Text('Counter'),
          centerTitle: true,
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                '${counter.count}',
                style: const TextStyle(fontSize: 30),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                  onPressed: () {
                    counter.increment();
                  },
                  child: const Text('Increase')),
              const SizedBox(height: 20),
              ElevatedButton(
                  onPressed: () {
                    counter.decreament();
                  },
                  child: const Text('Decrease')),
            ],
          ),
        ));
  }
}

				
			

Step 4: Hook Everything Up

Finally, update your main.dart to import and use CounterScreen.

				
					import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_tutorial/counter_screen.dart';
import 'provider/counter_provider.dart';

void main() {
  runApp(ChangeNotifierProvider(
      create: (context) => CounterProvider(), child: const MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Provider Tutorial',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const CounterScreen(),
    );
  }
}

				
			

Output

And there you have it! A simple counter app using Provider for state management. Tap that increase and decrease button like it’s your favorite arcade game and watch the magic happen.

I am pushing the whole code in the Github repository. Have a coffee and enjoy the learning.

Why Provider Rocks

 

Using Provider feels like having a superpower. Here’s why:

  1. Clean Code: Your code remains clean and readable. No more spaghetti code!
  2. Reactivity: Widgets rebuild only when necessary, making your app responsive and efficient.
  3. Scoped Access: You can access the state only where you need it, avoiding unnecessary rebuilds of the entire widget tree.

Advanced Provider Magic

 

But wait, there’s more! Provider isn’t just for simple use cases. It can handle complex scenarios with ease. In the next blog, we will talk about theme changing features using provider. That will be much more crunchy! Here is the blog  Change Your Theme Using the Power of Provider in Flutter

Here are a few advanced tips:

1. MultiProvider: Need more than one provider? Use MultiProvider to group them together.

				
					MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (context) => Counter()),
    ChangeNotifierProvider(create: (context) => AnotherModel()),
  ],
  child: MyApp(),
);

				
			

2. Consumer: For more fine-grained control, use Consumer to listen to changes in specific parts of your widget tree.

				
					Consumer<Counter>(
  builder: (context, counter, child) {
    return Text('${counter.count}');
  },
);

				
			

3. Selector: Optimize performance by listening to specific fields.

				
					Selector<Counter, int>(
  selector: (context, counter) => counter.count,
  builder: (context, count, child) {
    return Text('$count');
  },
);

				
			

Conclusion

 

There you have it, folks—a whirlwind tour of Provider for state management in Flutter. It’s a tool that makes managing state as easy as pie, and who doesn’t love pie? Whether you’re building a simple counter app or a complex, multi-screen monstrosity, Provider has got your back.

So, next time you’re wrangling with state management in Flutter, remember: there’s a Provider for that. Happy coding, and may your Flutter apps be ever responsive and bug-free!

Written and reviewed by

Picture of Muhammad Naeem
Muhammad Naeem
Professional Flutter Developer
Scroll to Top