Is it correct to add event to Bloc in initState or didChangeDependencies?
I tried to add event in initState and didChangeDependencies. But throw this exception.
But when this page opens again, everything work fine.
The following StateError was thrown building BlocBuilder<SlotsBloc, SlotsState>(dirty, dependencies: [_InheritedProviderScope<SlotsBloc?>], state: _BlocBuilderBaseState<SlotsBloc, SlotsState>#29045):
Bad state: No element
CodePudding user response:
I don't think this is how Bloc is intended to be used.
By reading a lot of examples on the official documentation, i see that the BlocProviders
are always placed somewhere within the widget tree.
This means that they are not accessible without a BuildContext
, so you can't access them in initState
or in didChangeDependencies
.
Another problem with this approach is that you are letting the user interface dictate state changes, and it should be the opposite.
CodePudding user response:
you can do sth like this:
BlocProvider<SlotsBloc>(
create: (context) => SlotsBloc()..add(SlotInitState()),
child: child
)
CodePudding user response:
There's no problem calling in initState
, it all depends on what you need.
See in the example that I instantiated the bloc inside the statefull, called an event and passed it to BlocBuilder
, with this you can use the bloc instance to add other events without having to read the context and at the same time I provide it to BlocBuilder, if you don't pass the bloc to BlocBuilder it will do the same thing you did in initState, run a BlocProvider.of<ExampleBloc>(context)
to access the instance in context.
Observer this official example from the documentation, github_Search.
class MyHomeStatefull extends StatefulWidget {
const MyHomeStatefull({Key? key}) : super(key: key);
@override
State<MyHomeStatefull> createState() => _MyHomeStatefullState();
}
class _MyHomeStatefullState extends State<MyHomeStatefull> {
late ExampleBloc exampleBloc;
@override
void initState() {
super.initState();
// instance bloc and insert event
exampleBloc = BlocProvider.of<ExampleBloc>(context)..add(StartEvent());
//or
//exampleBloc = context.read<ExampleBloc>()..add(StartEvent());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Page')),
body: BlocBuilder<ExampleBloc, ExampleState>(
bloc: exampleBloc,
builder: (context, state) {
if (state.isLoading) {
return const Center(child: CircularProgressIndicator());
}
return ListView(
children: List.generate(
state.listInterger.length,
(index) => ListTile(
title: Text('${state.listInterger[index]}'),
),
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: (){
exampleBloc.add(OtherEvent());
},
),
);
}
}