使用GetX时在build阶段调用Get.back()触发FlutterError如何解决?
问题原因
你在GetBuilder的builder回调里直接调用Get.back()时,正处于Widget的build阶段。导航操作会触发页面栈变化,进而引发新的Widget重建,而Flutter不允许在build过程中执行改变Widget树状态的操作,所以抛出setState() or markNeedsBuild() called during build错误。
解决方案
以下是三种可行的修复方式,推荐第二种更符合GetX状态管理逻辑的写法:
方案一:延迟到当前build帧完成后执行导航
使用WidgetsBinding.instance.addPostFrameCallback,把导航操作放到当前渲染帧完成后执行:
GetBuilder<TimerController>(builder: (controller) { if (controller.secondsRemaining == 0) { WidgetsBinding.instance.addPostFrameCallback((_) { Get.back(); }); } return Text('${controller.secondsRemaining}s', textAlign: TextAlign.right); })
方案二:将导航逻辑移到TimerController中(推荐)
把计时器到0后的返回逻辑放到控制器里,避免在UI层处理业务逻辑,代码分层更清晰:
修改TimerController:
class TimerController extends GetxController { int secondsRemaining = 5; late Timer timer; void startTimer() { timer = Timer.periodic(Duration(seconds: 1), (Timer t) { secondsRemaining--; update(); if (secondsRemaining <= 0) { stopTimer(); // 直接在控制器中触发返回 Get.back(); } }); } void stopTimer() { timer.cancel(); } }
PageB中只需负责显示文本:
GetBuilder<TimerController>(builder: (controller) { return Text('${controller.secondsRemaining}s', textAlign: TextAlign.right); })
方案三:用微任务延迟执行
通过Future.delayed(Duration.zero)将导航操作放到微任务队列,等当前build完成后执行:
GetBuilder<TimerController>(builder: (controller) { if (controller.secondsRemaining == 0) { Future.delayed(Duration.zero, () { Get.back(); }); } return Text('${controller.secondsRemaining}s', textAlign: TextAlign.right); })
内容的提问来源于stack exchange,提问作者magic_9527
相关产品推荐
相关产品推荐

