dkvirus / py-novel

看小说。服务端:【Python+Flask+Mariadb】、【Node+Express+Mariadb】;客户端:【Vue+iview】、【微信小程序】、【Android原生开发(Java)】、【Flutter+Dio】、【Taro+Typescript】
MIT License
129 stars 50 forks source link

Flutter报错:setState() called after dispose() #21

Closed dkvirus closed 5 years ago

dkvirus commented 5 years ago

报错信息

[ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
setState() called after dispose(): _ShelfState#5b9c1(lifecycle state: defunct, not mounted)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.

原因

上面英文大致意思是:在 Flutter 构件树被销毁后仍然执行了 setState 方法改变页面状态。

实际使用报错场景为:三个 tab,默认展示第一个 tab,点第三个 tab 时报的错。个人认为是 bottomNavigationBar 的 bug,点击第三个 tab,第二个 tab 的生命周期函数 initState 也执行了,这是不符合要求的。

解决

setState 之前加一句判断,当前页面是否存在于构件树中,存在赋值,不存在结束操作。

// mounted 为 true 表示当前页面挂在到构件树中,为 false 时未挂载当前页面
if (!mounted) {
  return;
}

setState(() {
  // xxxx
})