Flutter通过继承实现StatefulWidget时父组件UI不更新问题
ParentPage代码
class ParentPage extends StatefulWidget { @override ParentPageState createState() => ParentPageState(); } class ParentPageState<T extends ParentPage> extends State<T> { int counter = 0; void incrementCounter() => setState(() => counter++); @override Widget build(BuildContext context) => Text('$counter'); // 未更新 }
ChildPage代码
class ChildPage extends ParentPage { @override _ChildPageState createState() => _ChildPageState(); } class _ChildPageState extends ParentPageState<ChildPage> { @override Widget build(BuildContext context) { print('build[$counter]'); // 可正常更新 return Scaffold( body: ParentPage(), floatingActionButton: FloatingActionButton( onPressed: incrementCounter, child: Icon(Icons.add), ), ); } }
你在MaterialApp中配置了home: ChildPage(),点击FAB时_ChildPageState中的打印可以看到counter更新,但body里的Text始终显示0。
问题成因
- Flutter中每个
StatefulWidget实例都会绑定一个独立的State对象,状态存储在对应State实例中,不同Widget实例的状态完全隔离,不会跨实例共享,也不会因为类的继承关系自动同步。 - 你的场景中存在两个完全独立的
ParentPage体系组件实例:- 根路由的
ChildPage实例:它继承自ParentPage,绑定的State是_ChildPageState。你点击FAB调用的incrementCounter是这个State的方法,更新的也是这个State内部存储的counter变量,所以build方法中的打印可以拿到自增后的值。 _ChildPageState.build方法中通过body: ParentPage()新创建的ParentPage实例:它有自己独立的ParentPageState实例,这个State内部的counter默认值为0,且从未被触发过更新操作,所以它的build方法返回的Text组件始终显示0。
- 根路由的
修复方案
如果要复用父类ParentPage的build逻辑,不需要创建新的ParentPage实例,直接调用父类的build方法即可:
// 修改_ChildPageState的build方法中body的配置 body: super.build(context),
修改后点击FAB,body区域的Text就会正常展示自增后的counter值。
内容的提问来源于stack exchange,提问作者iDecode
相关产品推荐
相关产品推荐

