Published on

Flutter State Management with Bloc Core Concept Components - BlocProvider, BlocBuilder, BlocListener, BlocConsumer

Authors

1. BlocListener

Does not rebuild its child widget when the state changes. BlocListener is designed to listen for state changes and trigger side effects (like showing a dialog, navigating, or showing a snackbar) based on those changes. However, the child widget passed to BlocListener is not rebuilt when the state changes. If you want to rebuild a widget based on state changes, you should use a BlocBuilder. Here's a quick breakdown:

  • BlocListener: For reacting to state changes with side effects (no rebuilding).
  • BlocBuilder: For rebuilding the UI based on state changes.

Example of using BlocListener:

BlocListener<MyBloc, MyState>(
  listener: (context, state) {
    if (state is SomeSpecificState) {
      // Trigger a side effect here, like showing a Snackbar
    }
  },
  child: MyWidget(),  // This widget won't be rebuilt when the state changes.
);

If you want your widget to rebuild in response to state changes, you can use either BlocBuilder, BlocConsumer, or BlocProvider (with a BlocBuilder).

Here's a quick overview of when to use each:

2. BlocBuilder

Use this if you only need to rebuild your UI when the state changes, without triggering side effects like navigation or showing dialogs.

BlocBuilder<MyBloc, MyState>(
  builder: (context, state) {
    // Rebuild your widget based on the state
    return Text('State is: ${state.toString()}');
  },
);

3. BlocConsumer

This is a combination of both BlocListener and BlocBuilder. Use BlocConsumer if you need to both rebuild the widget and perform side effects based on state changes.

BlocConsumer<MyBloc, MyState>(
  listener: (context, state) {
    if (state is SomeSpecificState) {
      // Trigger side effects like showing a Snackbar or navigation
    }
  },
  builder: (context, state) {
    // Rebuild your UI here
    return Text('State is: ${state.toString()}');
  },
);

4. BlocProvider

BlocProvider is generally used to provide a bloc instance to the widget tree, not to rebuild widgets. It works together with BlocBuilder or BlocConsumer.

For example:

BlocProvider(
  create: (context) => MyBloc(),
  child: BlocBuilder<MyBloc, MyState>(
    builder: (context, state) {
      return Text('State is: ${state.toString()}');
    },
  ),
);

Summary:

  • Use BlocBuilder if you only need to rebuild the widget on state changes.
  • Use BlocConsumer if you need to both rebuild and perform side effects.
  • Use BlocProvider to provide the bloc instance to the widget tree, and then wrap your widgets with BlocBuilder or BlocConsumer to handle state changes.
  • Use BlocListener For reacting to state changes with side effects (no rebuilding).