I’m experimenting with Cubit in Flutter and wanted to create a ToggleCubit that handles multiple toggle actions (e.g., toggling between true and false).
Scenario
I initially added the BlocProvider at the top level of my widget tree, specifically at the Scaffold of my screen:
BlocProvider(
create: (context) => ToggleCubit(),
child: const Scaffold( ...
I intended to use this Cubit for toggling the show/hide password functionality and the checkbox state. However, as expected, changing one state affected the other because they share the same Cubit instance. I understand why this happens but was looking for a way to manage each toggle independently without having to create a separate BlocProvider for each widget.
Current Implementation
Option 1: Separate BlocProvider for Each Toggle
I added a separate BlocProvider for each widget so that they have independent states. Here’s how it looks:
Show/Hide Password:
BlocProvider(
create: (context) => ToggleCubit(),
child: BlocBuilder<ToggleCubit, bool>(
builder: (context, isPasswordVisible) {
return TextFormField(
obscureText: isPasswordVisible,
decoration: InputDecoration(
hintText: 'Password',
prefixIcon: Icon(PhosphorIcons.lock()),
suffixIcon: IconButton(
onPressed: () {
context.read<ToggleCubit>().toggle();
},
icon: Icon(isPasswordVisible
? PhosphorIcons.eyeSlash()
: PhosphorIcons.eye()),
),
),
);
},
),
),
Checkbox:
BlocProvider(
create: (context) => ToggleCubit(),
child: BlocBuilder<ToggleCubit, bool>(
builder: (context, isChecked) {
return Checkbox(
value: isChecked,
onChanged: (_) {
context.read<ToggleCubit>().toggle();
},
);
},
),
),
This approach works fine for small cases, but I’m not sure if it’s the best solution.
Option 2: Managing Multiple States in a Single Cubit
I also considered managing both the password visibility and checkbox states within a single Cubit. I modified the state to handle multiple properties:
Cubit State:
final class ToggleState {
final bool isChecked;
final bool isPasswordVisible;
ToggleState({
this.isChecked = false,
this.isPasswordVisible = false,
});
ToggleState copyWith({
bool? isChecked,
bool? isPasswordVisible,
}) {
return ToggleState(
isChecked: isChecked ?? this.isChecked,
isPasswordVisible: isPasswordVisible ?? this.isPasswordVisible,
);
}
}
Cubit Implementation:
class ToggleCubit extends Cubit<ToggleState> {
ToggleCubit() : super(ToggleState());
void passwordToggle() {
emit(state.copyWith(isPasswordVisible: !state.isPasswordVisible));
}
void checkboxToggle() {
emit(state.copyWith(isChecked: !state.isChecked));
}
}
Question
I’m unsure which approach is better for managing multiple toggle states. Is it more efficient or scalable to have a separate BlocProvider for each widget, or should I manage multiple states within a single Cubit? Are there other methods or best practices that I might have overlooked?
Any advice or suggestions would be greatly appreciated!