Understanding Cubit in Flutter: A Simplified Approach to State Management

Understanding Cubit in Flutter: A Simplified Approach to State Management

Introduction

Hey, Flutter devs! ???? After diving deep into Provider and Bloc, let’s simplify things a bit with Cubit—a lightweight state management solution built on top of Bloc.

If you love the power of Bloc but find the event-state mechanism a bit too much for some cases, then Cubit is for you!

What is Cubit?

Cubit is part of the Bloc package, but instead of using events, it directly exposes functions to change state. This makes it more straightforward, cleaner, and easier to manage for simpler state management needs.

With Cubit, you:

? Call functions instead of dispatching events.

? Emit new states directly.

? Avoid boilerplate code compared to Bloc.

Getting Started with Cubit

Let’s build a simple counter app using Cubit.

Step 1: Add Cubit to Your Project

Add the flutter_bloc package (Cubit is included inside Bloc):

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.1.3          
flutter pub get        

Step 2: Create the Cubit Class

Create a file counter_cubit.dart:

import 'package:bloc/bloc.dart';

class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0); // Initial state is 0

  void increment() => emit(state + 1);
  void decrement() => emit(state - 1);
}        

How it Works?

  • CounterCubit extends Cubit<int>, meaning it manages an integer state.
  • The initial state is 0.
  • emit(state + 1) updates the state when the increment function is called.


Step 3: Provide Cubit to Your App

Wrap your app in a BlocProvider inside main.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_cubit.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterScreen(),
    );
  }
}        

Step 4: Build the UI

Create counter_screen.dart:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_cubit.dart';

class CounterScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Cubit Counter Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('You have pushed the button this many times:'),
            BlocBuilder<CounterCubit, int>(
              builder: (context, count) {
                return Text(
                  '$count',
                  style: Theme.of(context).textTheme.headline4,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => context.read<CounterCubit>().increment(),
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
          SizedBox(width: 10),
          FloatingActionButton(
            onPressed: () => context.read<CounterCubit>().decrement(),
            tooltip: 'Decrement',
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}        

How it Works?

  • BlocBuilder<CounterCubit, int> listens for state changes.
  • FloatingActionButton triggers increment() and decrement().


Here's your next article for your LinkedIn newsletter, covering Cubit, a simplified alternative to Bloc.


Understanding Cubit in Flutter: A Simplified Approach to State Management

By Wael Abdallah Full Stack Developer @Callem.ai || Mobile Developer @CarNet || Software Engineering Student

Introduction

Hey, Flutter devs! ???? After diving deep into Provider and Bloc, let’s simplify things a bit with Cubit—a lightweight state management solution built on top of Bloc.

If you love the power of Bloc but find the event-state mechanism a bit too much for some cases, then Cubit is for you!

What is Cubit?

Cubit is part of the Bloc package, but instead of using events, it directly exposes functions to change state. This makes it more straightforward, cleaner, and easier to manage for simpler state management needs.

With Cubit, you: ? Call functions instead of dispatching events. ? Emit new states directly. ? Avoid boilerplate code compared to Bloc.

Bloc vs. Cubit: What’s the Difference?

FeatureBlocCubitUses events?? Yes? NoSimplicity? More boilerplate? Less boilerplateState UpdatesEvent → Bloc → StateFunction → emit(State)Best ForLarge-scale appsMedium to small apps


Getting Started with Cubit

Let’s build a simple counter app using Cubit.

Step 1: Add Cubit to Your Project

Add the flutter_bloc package (Cubit is included inside Bloc):

yaml        

CopyEdit

dependencies: flutter: sdk: flutter flutter_bloc: ^8.1.3 # Latest version as of (1/10/2024)

Run:

sh        

CopyEdit

flutter pub get


Step 2: Create the Cubit Class

Create a file counter_cubit.dart:

dart        

CopyEdit

import 'package:bloc/bloc.dart'; class CounterCubit extends Cubit<int> { CounterCubit() : super(0); // Initial state is 0 void increment() => emit(state + 1); void decrement() => emit(state - 1); }

How it Works?

  • CounterCubit extends Cubit<int>, meaning it manages an integer state.
  • The initial state is 0.
  • emit(state + 1) updates the state when the increment function is called.


Step 3: Provide Cubit to Your App

Wrap your app in a BlocProvider inside main.dart:

dart        

CopyEdit

import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'counter_cubit.dart'; void main() { runApp( BlocProvider( create: (context) => CounterCubit(), child: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: CounterScreen(), ); } }


Step 4: Build the UI

Create counter_screen.dart:

dart        

CopyEdit

import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'counter_cubit.dart'; class CounterScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Cubit Counter Example')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('You have pushed the button this many times:'), BlocBuilder<CounterCubit, int>( builder: (context, count) { return Text( '$count', style: Theme.of(context).textTheme.headline4, ); }, ), ], ), ), floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ FloatingActionButton( onPressed: () => context.read<CounterCubit>().increment(), tooltip: 'Increment', child: Icon(Icons.add), ), SizedBox(width: 10), FloatingActionButton( onPressed: () => context.read<CounterCubit>().decrement(), tooltip: 'Decrement', child: Icon(Icons.remove), ), ], ), ); } }

How it Works?

  • BlocBuilder<CounterCubit, int> listens for state changes.
  • FloatingActionButton triggers increment() and decrement().


When Should You Use Cubit?

Use Cubit when:

? You need better structure than setState(), but don’t want the complexity of Bloc.

? Your app has simple state transitions.

? You want less boilerplate.

Conclusion

Cubit is a powerful, simple, and lightweight alternative to Bloc. If you're managing state in a structured but minimal way, Cubit is a fantastic choice. It offers less boilerplate and more direct state management while keeping your Flutter app scalable and maintainable.

?? But Bloc and Cubit aren’t the only state management solutions in Flutter! In the next article, we’ll explore Riverpod, another modern and flexible approach that simplifies dependency injection and state management. Stay tuned!

?? Follow me on GitHub for more Flutter content: GitHub - Wael Abdallah

?? Learn more about Cubit on Pub.dev: flutter_bloc

Let’s keep building awesome Flutter apps! ????

要查看或添加评论,请登录

Wael ABDALLAH的更多文章

社区洞察