Flutter  

How to Manage State in Flutter Using Provider Step by Step

Introduction

When building mobile apps using Flutter, managing state is one of the most important concepts to understand. State simply means the data that changes over time, such as user input, API responses, or UI updates.

If state is not managed properly, your app can become difficult to maintain, buggy, and hard to scale. This is where state management solutions like Provider come in.

Provider is one of the most popular and beginner-friendly state management techniques in Flutter. It helps you manage and share data across your app efficiently.

In this article, we will learn how to manage state in Flutter using Provider step by step with simple explanations and practical examples.

What is State in Flutter?

In Flutter, state refers to any data that can change during the lifecycle of the app.

Examples:

  • Counter value

  • User login status

  • API data

  • Theme changes

There are two types of state:

  • Local State → Managed within a single widget

  • Global State → Shared across multiple widgets

Provider is mainly used for managing global state.

What is Provider in Flutter?

Provider is a wrapper around InheritedWidget that makes state management easier and more efficient.

It allows you to:

  • Store data in one place

  • Access data anywhere in the widget tree

  • Update UI automatically when data changes

Why Use Provider for State Management?

Provider is widely used because:

  • Simple and easy to learn

  • Lightweight and efficient

  • Reduces boilerplate code

  • Works well with Flutter architecture

Step 1: Add Provider Dependency

First, add the Provider package to your project.

dependencies:
  provider: ^6.0.0

Then run:

flutter pub get

Step 2: Create a Model Class

Create a class that holds your state.

import 'package:flutter/material.dart';

class CounterModel extends ChangeNotifier {
  int _count = 0;

  int get count => _count;

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

Explanation:

  • ChangeNotifier → notifies UI when data changes

  • notifyListeners() → rebuilds widgets

Step 3: Provide the Model to the App

Wrap your app with ChangeNotifierProvider.

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

This makes the state available across the app.

Step 4: Access State in UI

Use Consumer or Provider.of to access data.

Example using Consumer:

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

This rebuilds UI when count changes.

Step 5: Update State from UI

Call methods from the model.

ElevatedButton(
  onPressed: () {
    Provider.of<CounterModel>(context, listen: false).increment();
  },
  child: Text('Increment'),
)

This updates the state and UI automatically.

Step 6: Using Provider.of vs Consumer

  • Provider.of → Direct access

  • Consumer → Rebuilds only required widgets

Best practice:

  • Use Consumer for UI updates

  • Use Provider.of for actions

Step 7: Organizing Code Structure

For larger apps:

  • models/ → state classes

  • providers/ → business logic

  • screens/ → UI

This keeps code clean and maintainable.

Step 8: Using MultiProvider

When using multiple providers:

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CounterModel()),
    ChangeNotifierProvider(create: (_) => AnotherModel()),
  ],
  child: MyApp(),
)

This helps manage multiple states easily.

Step 9: Avoid Common Mistakes

  • Forgetting notifyListeners()

  • Using listen: true in wrong places

  • Rebuilding entire UI unnecessarily

Real-World Example

Use Provider for:

  • Shopping cart state

  • User authentication

  • Theme switching

  • API data handling

Best Practices for Provider

  • Keep models simple

  • Separate UI and logic

  • Use Consumer for performance

  • Avoid deeply nested providers

Summary

Provider is a powerful and simple state management solution in Flutter. By using ChangeNotifier, Consumer, and proper structure, you can manage app state efficiently and build scalable applications. Following a step-by-step approach helps you understand how data flows and how UI updates automatically, making your Flutter development smoother and more maintainable.