skip to Main Content

I am practicing with flick_bloc and I wonder when to use BlocBuilder, when to use BlocListener and when to use BlocConsumer. I asked a few people, they said that BlocBuilder is used the most and I also started and just practiced with it, but it seems that Blocbuilder only changed for the first time, I don’t know if it’s true. Can you guys give me some comments on these spellings

3

Answers


  1. BlocBuilder: You can use it to just build out your widgets, but the draw back is that you can’t build in Snackbars or Dialogs into the flow, because you must return a widget in blocbuilder and you don’t want to return a snackbar or dialog.

    BlocListener: This would permit you to use your dialogs and snackbars, but the issue is that it can’t let you do anything a blocbuilder would let you do. Which is as you might have guessed, is to return a widget, it’s more suited for dismissible UI components like the dialogs and snackbars.

    BlocConsumer: This widget helps you combine both a BlocListener and a BlocBuilder, so you can return static components and dismissible UI components.

    So if you won’t need Snackbars or Dialogs, use a BlocBuilder, If you need Snackbars or Dialogs, use a BlocListener. If you want both of them to work in synergy use a BlocConsumer.

    Login or Signup to reply.
  2. Bloc Builder

    • Used for building widgets, For Example: If you want to show a list of employee names on a page, you can return a ListView widget based on the bloc state. Also, if the employee list comes from an API, then you will need different states such as Loading, Success and Failure states. Based on these different states you can return different widgets from BlocBuilder. A CircularProgressIndicator for showing loading state, ListView for showing employee list in the success state and Error text widget for showing error message if the API fails.
    BlocBuilder<BlocA, BlocAState>(
      builder: (context, state) {
        if (state is Loading) {
          return CircularProgressIndicator();
        }
      }
    )
    

    Bloc Listener

    • BlocBuilder can only return widgets. If you want to show a snackbar or want to Navigate from one page to another, then you need to use BlocListener for that.
    BlocListener<BlocA, BlocAState>(
      listener: (context, state) {
        if (state is Success) {
          Navigator.push(context,
           MaterialPageRoute(builder: (context) => const SecondRoute()),
         );
        }
      }
    )
    

    Bloc Consumer

    • If you have the use of both BlocListener and BlocBuilder, then it is better to use BlocConsumer. It reduces the boilerplate of using BlocListener and BlocBuilder together.

    Code Without Bloc Consumer:

    BlocListener<BlocA, BlocAState>(
      listener: (context, state) {
        if (state is Success) {
          Navigator.push(context,
           MaterialPageRoute(builder: (context) => const SecondRoute()),
         );
        }
      },
      child: BlocBuilder<BlocA, BlocAState>(
      builder: (context, state) {
        if (state is Loading) {
          return CircularProgressIndicator();
        }
      }
     ),
    )
    

    Code using Bloc Consumer:

    BlocConsumer<BlocA, BlocAState>(
      listener: (context, state) {
        if (state is Success) {
          Navigator.push(context,
           MaterialPageRoute(builder: (context) => const SecondRoute()),
         );
        }
      },
      builder: (context, state) {
        if (state is Loading) {
          return CircularProgressIndicator();
        }
      }
    )
    
    Login or Signup to reply.
  3. BlocBuilder

    This is used when we want to draw a Widget based on what is the current State. In the following example a new “text” gets drawn every time the state changes.

    Sample Example

    BlocBuilder<OrdersBloc, OrdersState>(
     buildWhen: (context, state) {
      return state is OrdersState.OrderCompleted
     },
     builder: (context, state) {
      if (state is OrdersState.OrderCompleted) {
       return Container(child: Text('Order Completed!'));
      } else if (OrdersState.OrderInProgress) {
       return Container(child: Text('In Progress'));
      } else if (OrdersState.OrderRequested) {
       return Container(child: Text('A customer placed an order!'));
      } else {
       return Container(child: Text('Waiting for an order'));
      }
     },
    );
    

    BlocListener

    This is just a listener not a builder (like the above), that means that its job is keep listening for new changes in the state and not to return a widget. You can use listener when you want to show any dialog or any toast, or navigation from one page to another(these are few examples).

    Sample Example

    BlocListener<OrdersBloc, OrdersState>(
     listenWhen: (context, state) {
      return state is OrdersState.OrderCompleted;
     },
     listener: (context, state) {
      // Navigate to next screen
      Navigator.of(context).pushNamed('OrderCompletedScreen');
     },
     child: Container(child: Text('Always draw this text!')),
    );
    

    BlocConsumer
    This is used when we want to draw something based on the current state and execute some actions depending on the new arriving states. This is a mix between “BlocListener” and “BlocBuilder”.

    Sample Example

    BlocConsumer<OrdersBloc, OrdersState>(
     listenWhen: (context, state) {
      return state is OrdersState.OrderCompleted ||
        state is OrdersState.OrderRefunded;
     },
     listener: (context, state) {
      if (state is OrdersState.OrdersCompleted) {
       // Navigate to next screen
       Navigator.of(context).pushNamed('OrderCompletedScreen');
      } else if (state is OrdersState.OrderRefunded) {
       // Report to analytics
       Analytics.reportRefunded(state.orderId);
      }
     },
     buildWhen: (context, state) {
      return state is OrdersState.OrderCompleted ||
        state is OrdersState.OrderInProgress ||
        state is OrdersState.OrderRequested;
     },
     builder: (context, state) {
      if (state is OrdersState.OrderCompleted) {
       return Container(child: Text('Order Served!'));
      } else if (OrdersState.OrderInProgress) {
       return Container(child: Text('In Progress'));
      } else {
       return Container(child: Text('No State'));
      }
     },
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search