为什么StatelessWidget的数据在修改后界面没变化?
我在用StatelessWidget实现一个计数器,点击按钮时调用父组件的回调修改数据,但界面始终没变化。已经确认数据确实更新了,也尝试过用setState()强制刷新父组件,但子组件显示的数值还是没变,这是为什么?
代码结构大概是这样:
// 父组件
class Parent extends StatefulWidget {
@override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
int count = 0;
void increment() {
setState(() {
count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
StatelessCounter(count: count),
ElevatedButton(onPressed: increment, child: Text('增加'))
],
);
}
}
// 子组件
class StatelessCounter extends StatelessWidget {
final int count;
StatelessCounter({required this.count});
@override
Widget build(BuildContext context) {
return Text('当前计数:$count');
}
}
按钮能正常触发increment方法,但Text显示的count值始终是初始值0,有没有哪里没传值对?
把 StatelessCounter 的 build 改成:
或者确认父组件确实重新 build 了整个 StatelessCounter。
只要父组件 setState 后重建 Column,子组件就会拿到新 count,界面自然刷新。就这样。
StatelessWidget 本身不会主动刷新,除非父组件 rebuild 的时候传进来的参数发生变化。你虽然调用了 setState(() { count++; });,但只触发了 Parent 组件的 build,StatelessCounter 作为子组件,虽然接收到了新的 count 值,但因为它自己没有 Key 或者其他变化标识,Flutter 认为它不需要 rebuild,所以 UI 就没更新。
解决方法很简单:
给 StatelessCounter 加一个 Key,比如 ValueKey
改一下父组件 build 里这行:
改成:
这样一来,每次 count 变化,Flutter 会识别到 key 不一样了,就会重建 StatelessCounter,Text 也就能显示最新的值了。
说白了,这就是 Flutter 的渲染优化机制在作怪,你以为传值进去了它就会更新,但它一看 key 没变,就直接跳过了 build 子组件这一步。加个 key,骗骗它就好了。