Which way to use freezed library with bloc ? first one as a sealed classes, the other is a constructor.
First way
abstract class HomeState with _$HomeState {
const factory HomeState.initial() = _Initial;
const factory HomeState.addNewNoteButtonClicked(@Default(false) bool isClicked) = AddNewNoteClicked;
factory HomeState.addNewNote( Note value) = AddNewNote;
}
Second Way:
abstract class HomeState with _$HomeState {
const factory HomeState({
required Note value,
required bool isClicked,
}) = AddNewNoteClicked;
factory HomeState.init() => HomeState(
value: Note(value: ''),
isClicked: false,
);
}
TL;DR: I think there is no correct way, just what works for you.
When using freezed, every factory constructor generates a separate class. Together with that, it generates some convenience methods, like map
/maybeMap
/when
/maybeWhen
. This is very convenient when your BLoC has obvious and different states and you want to handle your UI accordingly. For instance: initial
, loadInProgress
, loadSuccess
, loadFailure
. Then, in your UI, you could use something like:
class Example extends StatelessWidget {
const Example();
@override
Widget build(BuildContext context) {
return BlocBuilder<ExampleCubit, ExampleState>(
builder: (_, state) => state.maybeWhen(
loadInProgress: () => const LoaderView(),
loadFailure: () => const ErrorView(),
loadSuccess: (categories) => const SomeView(),
orElse: () => const SizedBox(),
),
);
}
}
However, it also brings some inconvenience when you need to take data from the specific state: you must check if the state is a specific one and only then you can process with your code, e.g:
if (state is ExampleStateSuccess) {
...
}
In such cases, when you need to have just a single state but a lot of different properties (a good example would be form validation when you store all the field properties in your BLoC and you want to validate/update them, submit the form later) it is better to use a single state with properties. By better, I mean it's just easier this way.