Closed yun-cheng closed 2 years ago
Thanks for reports. I'll review this ASAP.
@yun-cheng, Is there any value that is rebuilding your widget?
@kranfix Yes, I also use useState
to rebuild this widget when keyboard visibility changed. But I don't think it's relevant.
I just wrote my own version of useBloc
and seems like solving this problem. Not fully tested yet.
The buildWhen
here is slightly different from the original buildWhen
from BlocBuilder.
It compares the current state to last saved state (with ValueNotifier), not comparing the sequential state.
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
S useBloc<B extends BlocBase<S>, S>({
bool Function(S previous, S current)? buildWhen,
}) {
final bloc = useContext().read<B>();
final state = useState(bloc.state);
useEffect(() {
final stream = bloc.stream.listen((currentState) {
if (buildWhen != null ? buildWhen(state.value, currentState) : true) {
state.value = currentState;
}
});
return () => stream.cancel();
}, []);
return state.value;
}
Edit: I think the problem is gone.
Yes, that is beacuse you are keeping the state, while the useBloc(..).state
reads the current state. Despite the onEmitted is not rebuilding the widget, another state does.
Then, I will make a breaking change:
// before
final state = useBloc<MyBloc, MyState>().state;
// after
final state = useBloc<MyBloc, MyState>();
Thus, the state
will keep the latest emitted state instead of the current state.
If someone wants to read the bloc
, now it is possible to use final myBloc = context.read<MyBloc>()
.
This version fix the problem.
https://pub.dev/packages/flutter_hooks_bloc/versions/0.16.0
I noticed
useBloc
is not using the correct state whenonEmitted
returntrue
sometimes. Maybe because rapidly changing of state. Here's simplified demonstration of my usage.Not sure what went wrong. Is it possible that it's using the next state or previous state?
Btw, BlocBuilder works fine with the same expression writing in
buildWhen
.