Flutter: Diferencias BlocBuilder, BlocConsumer y BlocListener

Pablo Reyes
3 min readJan 17, 2021
Photo by Azazello BQ on Unsplash

Comenzar a utilizar BLoC en una aplicación con Flutter puede llegar a ser bastante confuso y frustrante por la dudas que pueden causar algunos conceptos, como lo son BlocListener, BlocBuilder y BlocConsumer.

Entonces cuando usar estos? … Supongamos que estamos haciendo una aplicación que procesa ordenes de un restaurante. Debido a que estamos utilizando BLoC tenemos OrdersEvent y OrdersState.

  • OrdersEvent: PlaceAnOrder, PayAnOrder, CancelOrder
  • OrdersState: OrderRequested, OrderInProgress, OrderCompleted, OrderRefunded

BlocBuilder

Este es el mas sencillo de los tres. Este es utilizado solo cuando se quiere dibujar un Widget dependiendo el State (estado) que recibamos. En el siguiente ejemplo dibujamos un texto diferente cada vez que el estado cambie.

En este caso el builder solo se manda a llamar la primera vez y cuando ocurre un rebuild y devuelve true (para este caso el estado “OrderCompleted”)
  • buildWhen (Opcional): Este nos sirve como bandera true o false para identificar si queremos que se ejecute el método de builder cuando ocurra un proceso de rebuild (descrito mas adelante). Si se devuelve true se ejecuta el builder y con false no se ejecuta. Si este no se agrega, entonces el builder va a ser ejecutado siempre cuando ocurra un proceso de rebuild.
  • builder (Requerido): Este método es el más importante, es el que devuelve que Widget queremos dibujar utilizando como base cuál es el estado actual. Por ejemplo: Si el estado es OrderState.OrderCompleted entonces se dibuja el widget con texto “Order Completed!”.

BlocListener

Este se utiliza para cuando queremos estar constantemente escuchando todos los cambios que hay en los estados, en este caso OrdersState. Cada vez que exista un cambio BlocListener recibirá una notificación lo cual permita poder ejecutar una acción.

Cuando utilizamos BlocListener lo que dibujamos en pantalla no depende del estado actual (OrdersState), sino que este es utilizado para conocer el estado actual y realizar una acción que no es dibujar un widget. Por ejemplo: Mandar un evento para analytics, hacer un API request, cambiar de pantalla, etc.

En este caso el listener solo se manda a llamar la primera vez y cuando ocurre un rebuild y devuelve true (en otras palabras “OrderCompleted”)
  • listenWhen (Opcional): Este nos sirve como bandera true o false para identificar si queremos que se ejecute el método de listener cuando ocurra un proceso de rebuild (descrito mas adelante). Si se devuelve true se ejecuta el listener y con false no se ejecuta. Si este no se agrega, entonces el listener va a ser ejecutado siempre cuando ocurra un proceso de rebuild.
  • listener: Este método es el más importante, recibe el estado actual y permite que podamos realizar una acción con base a eso. Por ejemplo: Navegar a otra pantalla, mandar algo a analytics, mostrar un dialog o animación, hacer un API request, etc.

BlocConsumer

Este una union entre BlocBuilder y BlocListener. Este se utiliza cuando queremos dibujar algo con base al estado (OrdersState) y por otra parte queremos tomar acciones (e.g. Reportar Analytics) con base al estado.

Donde listenWhen y buildWhen son opcionales.

Donde builder hace lo mismo que en BlocBuilder, y listener hace lo mismo que en BlocListener.

Qué es rebuild y cuando ocurre?

Es cuando el BuildOwner indica que el widget esta dirty (sucio) entonces vuelve a llamar el método build (para volver a dibujar el widget). Esto ocurre solo cuando el widget ya esta construido e hizo build la primera vez.

Aplicándolo a buildWhen y listenerWhen estos métodos solo se mandan a llamar durante el proceso de rebuild, en otras palabras la primera vez que se dibuja el widget estos métodos no se mandan a llamar por lo tanto el widget se va a dibujar con base al estado actual que se esta recibiendo. Y luego cuando reciba un rebuild va a verificar primero buildWhen o listenerWhen para comprobar si debe hacer rebuild o no.

Nota: Tomemos en cuenta que el rebuild es muy costoso a nivel de performance, es por esta razón que existen estos flags de buildWhen and listenerWhen para evitar un rebuild innecesario y no solo un rebuild que no queremos.

En conclusión BlocListener y BlocBuilder son diferentes, y BlocConsumer es una mezcla de ambos.

Es importante notar que si no se necesita ejecutar un acción con base al estado o dibujar algo con base al estado entonces no hay necesidad de utilizar ni BlocListener, BlocConsumer o BlocBuilder.

--

--