Corporate Training
Request Demo
Click me
Menu
Let's Talk
Request Demo

Tutorials

State Management in Flutter

22. State Management in Flutter (Provider, Bloc, Mobx)

State management is a critical aspect of building Flutter applications. Flutter offers various approaches to handle state, including Provider, Bloc (Business Logic Component), and MobX. In this tutorial, we'll explore each of these state management techniques with examples.

1. Provider

Provider is a straightforward state management solution that comes with the Flutter ecosystem. It helps manage state efficiently, especially for widget trees.

Step 1: Add the 'provider' Package

In your 'pubspec.yaml' file, add the 'provider' package as a dependency:
dependencies:
  flutter:
    sdk: flutter
  provider: ^latest_version
 

Run 'flutter pub get' to fetch the package. Make sure to replace '^latest_version' with the latest version available on pub.dev.

Step 2: Create a Model Class

Define a model class to represent your application's data. For example, let's create a simple 'Counter' model:
class Counter {
  int value = 0;

  void increment() {
    value++;
  }
}
 

Step 3: Implement Provider

Wrap your app with a 'ChangeNotifierProvider' or 'provider' widget at the top level of your widget tree. In this example, we'll use 'ChangeNotifierProvider':
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

Step 4: Use Provider

Access and modify the state using the 'provider.of' method in your widgets:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = Provider.of(context);

    return MaterialApp(
      title: 'Provider Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Provider Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Count:',
                style: TextStyle(fontSize: 20),
              ),
              Text(
                '${counter.value}',
                style: TextStyle(fontSize: 40),
              ),
              ElevatedButton(
                onPressed: () {
                  counter.increment();
                },
                child: Text('Increment'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
 

This example creates a simple counter app using the Provider package.

2. Bloc (Business Logic Component)

Bloc is a pattern for managing the state of a Flutter application that separates business logic from presentation.

Step 1: Add the 'flutter_bloc'Package

In your 'pubspec.yaml' file, add the 'flutter_bloc' package as a dependency:
dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^latest_version
 

Run 'flutter pub get' to fetch the package. Replace '^latest_version' with the latest version available on pub.dev.

Step 2: Create a Bloc

Define a Bloc class to handle your application's business logic. Let's create a simple 'CounterBloc':
import 'package:flutter_bloc/flutter_bloc.dart';

enum CounterEvent { increment }

class CounterBloc extends Bloc {
  CounterBloc() : super(0);

  @override
  Stream mapEventToState(CounterEvent event) async* {
    if (event == CounterEvent.increment) {
      yield state + 1;
    }
  }
}
 

Step 3: Implement Bloc

Initialize and use the 'CounterBloc' in your widget tree:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final counterBloc = CounterBloc();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Bloc Example',
      home: BlocProvider(
        create: (context) => counterBloc,
        child: MyHomePage(),
      ),
    );
  }
}
 

Step 4: Use Bloc

Access and modify the state using the 'BlocBuilder' widget:
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bloc Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            BlocBuilder(
              builder: (context, state) {
                return Text(
                  'Count:',
                  style: TextStyle(fontSize: 20),
                );
              },
            ),
            BlocBuilder(
              builder: (context, state) {
                return Text(
                  '$state',
                  style: TextStyle(fontSize: 40),
                );
              },
            ),
            ElevatedButton(
              onPressed: () {
                context.read().add(CounterEvent.increment);
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}
 

This example creates a simple counter app using the Bloc pattern.

3. MobX

MobX is a state management library that simplifies managing state and the UI by using reactive programming.

Step 1: Add the 'mobx' and 'flutter_mobx' Packages

In your 'pubspec.yaml' file, add the 'mobx' and 'flutter_mobx' packages as dependencies:
dependencies:
  flutter:
    sdk: flutter
  mobx: ^latest_version
  flutter_mobx: ^latest_version
 

Run 'flutter pub get' to fetch the packages. Replace '^latest_version' with the latest version available on pub.dev and pub.dev.

Step 2: Create a MobX Store

Define a MobX store class to handle your application's state. Let's create a simple 'CounterStore':
import 'package:mobx/mobx.dart';

part 'counter_store.g.dart';

class CounterStore = _CounterStore with _$CounterStore;

abstract class _CounterStore with Store {
  @observable
  int value = 0;

  @action
  void increment() {
    value++;
  }
}
 

Step 3: Generate MobX Code

Run the following command to generate MobX-related code:
flutter packages pub run build_runner build
 

This generates the necessary files, including 'Counter_store.g.dart'.

Step 4: Implement MobX

Initialize and use the 'CounterStore' in your widget tree:
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';

import 'counter_store.dart'; // Import the CounterStore class

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final counterStore = CounterStore();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MobX Example',
      home: MyHomePage(counterStore: counterStore),
    );
  }
}
 

Step 5: Use MobX

Access and modify the state using the 'Observer' widget:
class MyHomePage extends StatelessWidget {
  final CounterStore counterStore;

  MyHomePage({required this.counterStore});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MobX Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Count:',
              style: TextStyle(fontSize: 20),
            ),
            Observer(
              builder: (_) {
                return Text(
                  '${counterStore.value}',
                  style: TextStyle(fontSize: 40),
                );
              },
            ),
            ElevatedButton(
              onPressed: () {
                counterStore.increment();
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}
 

This example creates a simple counter app using the MobX state management library.

Conclusion:

State management is crucial for building Flutter applications, and each approach has its use cases. Provider is excellent for small to medium-sized apps, Bloc is suitable for complex apps with a lot of business logic, and MobX offers a reactive approach to state management. Choose the one that best fits your project's needs and complexity.