Describe the bug
Bad state: Cannot add new events after calling close
To Reproduce
Steps to reproduce the behavior:
Note: If I use BlocBuilder.value, the program works normally
class _HomePageState extends State<HomePage> {
HomeBloc _bloc;
List<Note> _listNote;
@override
void initState() {
_bloc = HomeBloc(context: context);
_bloc.dispatch(LoadNoteDataEvent());
_listNote = List();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[100],
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => BlocProvider(
builder: (context) => _bloc,
child: ItemWidget(),
),
itemCount: _listNote.length,
),
),
RaisedButton(
child: Text('OK'),
//The error was thrown when I pressed the button
onPressed: () => _bloc.dispatch(HandleTapEvent()),
)
],
),
);
}
}
This is expected behavior... BlocProvider manages the life cycle of the bloc and when it's disposed will also automatically dispose of the bloc. Which is why you are seeing the behavior you described. Using BlocProvider.value is the recommended way in this situation.
Check out the documentation here: https://felangel.github.io/bloc/#/flutterbloccoreconcepts?id=blocprovider
Hi @hahai96 馃憢
Thanks for opening an issue!
As @warriorCoder mentioned, when you use BlocProvider with a builder, then the BlocProvider will automatically dispose the bloc when BlocProvider is disposed. In addition, you should always create the bloc instance within the builder in order to avoid this type of issue.
If you really want to have the Bloc be created within this widget, then you have to use BlocProvider.value and manually dispose the bloc yourself. Alternatively, I'd suggest wrapping your HomePage in a BlocProvider like:
BlocProvider(
builder: (context) => HomeBloc()..dispatch(LoadNoteDataEvent()),
child: HomePage(),
)
Then everything should work as expected and you don't need to manually dispose and create the bloc within a StatefulWidget.
Some other things to consider are:
BuildContext to a bloc because you are coupling the bloc to Flutter and are making the business logic layer have a dependency on the presentation layer._listNote seems like it should be part of the bloc state instead of being separately maintained by the widgetHope that helps! 馃憤
You should not be passing BuildContext to a bloc because you are coupling the bloc to Flutter and are making the business logic layer have a dependency on the presentation layer.
@felangel In case I need to use context, what should I do?
@hahai96 why do you need BuildContext within the bloc?
@felangel because I did not use respository, I will refactor my code.
BlocProvider(
builder: (context) => HomeBloc()..dispatch(LoadNoteDataEvent()),
child: HomePage(),
)
@felangel When will blocProvider dispose. For my original code, I think it was only dispose when the Homepage was dispose
@hahai96 it will dispose the bloc when the BlocProvider widget is disposed. In your original implementation, BlocProvider was being disposed before the HomePage was disposed and you were using dispatch outside of BlocProvider.
Most helpful comment
This is expected behavior... BlocProvider manages the life cycle of the bloc and when it's disposed will also automatically dispose of the bloc. Which is why you are seeing the behavior you described. Using BlocProvider.value is the recommended way in this situation.
Check out the documentation here: https://felangel.github.io/bloc/#/flutterbloccoreconcepts?id=blocprovider