Flutter Web中调用setState后组件未重渲染,求问题排查
问题根源及解决方案
你的代码核心问题是将需要维护状态的testMap和wow变量声明在了build方法内部。
每次调用setState后,Flutter会重新执行build方法,而你在build里每次都会重新初始化testMap = {"one": 5, "two": 3}和wow = "wow",直接覆盖了setState里的修改,导致UI没有更新。移动端看似正常是偶然的渲染时机差异,但写法本身存在错误。
修复步骤
- 将
testMap和wow提升为组件的成员变量,移到build方法外部:
class YourWidgetState extends State<YourWidget> { // 作为状态成员变量维护 Map<String, dynamic> testMap = {"one": 5, "two": 3}; String wow = "wow"; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Text(testMap.toString()), Text(wow), ElevatedButton( onPressed: () { setState(() { testMap = SplayTreeMap<String, dynamic>.from(testMap, (k1, k2) => testMap[k1].compareTo(testMap[k2])); wow = "hey"; }); print(testMap.toString()); }, child: const Text("sort")) ], ), ); } }
- 额外优化:
SplayTreeMap的排序逻辑中,建议提前缓存键对应的值,避免因testMap被替换导致的潜在逻辑问题:
testMap = SplayTreeMap<String, dynamic>.from(testMap, (k1, k2) { final val1 = testMap[k1]; final val2 = testMap[k2]; return val1.compareTo(val2); });
修改后,setState修改的是组件的成员变量,build方法执行时会使用更新后的值,Web和移动端都会正常触发重渲染。
内容的提问来源于stack exchange,提问作者Akira Yoshimura
相关产品推荐
相关产品推荐

