This repository contains a minimal implementation of Cubits from package:flutter_bloc
in Flutter.
Whilst I don't make use of the Bloc
state management system, I am making use of its little brother: Cubit
. In the rest of this README you'll find my notes synthesising what I was able to learn from the generous sources listed below.
Documentation and Tutorials:
package:flutter_bloc
- Dart Docs- Core concepts (package:flutter_bloc) - bloc
- What is the BLoC Pattern? - flutterclutter.dev
- Cubits in Flutter: A Practical Guide - Amos Gross
The difference: BLoC
Bloc
s and Cubit
s are not widgets or data representation. Instead they stand between those two things, exposing functionality to the widgets so that actions can be invoked from the UI, and manipulating data in a controlled manner. They help prevent tight coupling between an application's data and presentation layers.
Architectural overview:
- State: An object (encapsulated data model/representation) relevant to some aspect of an application. It is the thing actually being passed around--the state being managed.
- State Manager: An object existing between UI and state which handles the manipulation of data based on user interaction with the UI layer, and the subsequent delivery of updated state back to the UI from the data layer.
- Provider: A widget which should be inserted high up into the tree such that its subtree contains the widgets which uses the state(s) that it is providing and managing.
- Consumer: A widget which should be inserted into a provider's subtree such that it can access it via
context
.
State Manager:
Bloc
: An object which exposes event triggers the UI layer and contains event-handling procedures to manipulate the data layer and output resultingstate
s accordingly.Cubit
: An object passed down through the UI layer exposing methods which can directly manipulatestate
and subsequently return it to be provided again. It is essentially aBloc
which exposes methods which can be directly called, as opposed to a suite of events, thereby "removing a step".
Provider Widgets:
BlocProvider
: Initialises aBloc
orCubit
object and contains a subtree which has consumers.MultiBlocProvider
: Contains a listBlocProvider
to avoid nestingBlocProviders
where multiple are necessary, thereby creating multiple instances ofBloc
s orCubit
s for multifaceted state management.
Consumer Widgets:
BlocBuilder
: Builds a new widget in response to a change instate
.BlocListener
: Listens for a change instate
and calls thelistener
callback function exactly once for each change instate
.MultiBlocListener
: Contains a list ofBlocListener
s to avoid nestingBlocListener
s where multiple are necessary, thereby containing multiplelistener
s to respond to changes instate
in a multifaceted manner.BlocComsumer
: Literally combines the functionality ofBlocBuilder
andBlocListener
together into a single widget to allow for both alistener
andbuilder
callback.BlocSelector
: Calls itsselector
callback which returns astate
to be used by thebuilder
callback when building the widget, essentially allowing for preprocessing of astate
prior to building.
Utility Classes/Typedefs:
Change
: A class for representing a change in state comprised acurrentState
andnextState
field holdingstate
s of the same type but possibly having different values. They are created whenever a state change occurs, being accessible using a BlocObserver for monitoring purposes.Emitter
: A class used by anEventHandler
with acall()
method which emits a state.EventHandler
: A typedef representing a function tying an event (which can be any type of data) to anEmitter
which emits a state in response. They are responsible for reacting to incoming events and emitting zero or more states in response when using aBloc
.Transition
: A class for representing a change from one state to another along with the event which incited that change. They are created whenever a state change occurs as a result of an event, being accessible using aBlocObserver
for monitoring purposes.