As we know, if we setState
during a widget build, it will error:
flutter: [extra#0] bound_extra.0 => FlutterError.onError raw stackTrace=#0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4424:11)
flutter: #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4439:6)
flutter: #2 ObserverElementMixin.invalidate (package:flutter_mobx/src/observer_widget_mixin.dart:71:24)
flutter: #3 ReactionImpl._run (package:mobx/src/core/reaction.dart:117:22)
flutter: #4 ReactiveContext._runReactionsInternal (package:mobx/src/core/context.dart:351:18)
flutter: #5 ReactiveContext.runReactions (package:mobx/src/core/context.dart:325:5)
flutter: #6 ReactiveContext.endBatch (package:mobx/src/core/context.dart:155:7)
flutter: #7 ActionController.endAction (package:mobx/src/core/action.dart:110:9)
flutter: #8 AsyncAction._run (package:mobx/src/api/async/async_action.dart:46:16)
...
And the simple solution is to use addPostFrameCallback
and do setState
there.
However, in my case, I hope there exists a smartSetState
which does the following:
- Whenever possible, it calls
setState
directly. Thus, we do not have a one-frame latency. - If not possible (i.e. direct
setState
will lead to the error above), it waits for a frame andsetState
then.
How can this be implemented? I have searched whether there exists some state variable indicating whether the widget tree is building, but no results. Thanks!
P.S. I know there are already questions like setState() or markNeedsBuild called during build, but I hope the smartSetState
can automatically determine whether to wait or not, instead of blindly wait for a frame.