Flutter报错:setState()或markNeedsBuild()在build期间调用
解决Flutter中
setState() or markNeedsBuild() called during build错误 问题根源
你的代码存在两个核心问题触发了该错误:
- 构建过程中触发状态更新:
build方法内调用了provider.initialize(),该方法内部会执行notifyListeners(),而Flutter禁止在组件构建流程中触发状态通知,否则会引发构建冲突。 - 构建时直接修改State成员变量:
mainBody方法中直接给_heading、_name等State类的成员变量赋值,这属于在构建阶段修改状态,会打乱Flutter的构建时序。
修复方案
1. 移除build方法中的初始化调用
将provider.initialize()从build方法中移除,移到initState中执行,确保初始化逻辑只运行一次,避免在每次构建时触发状态更新。
2. 避免构建过程中直接修改State变量
通过setState方法更新本地状态,而非在构建流程中直接赋值,确保状态变更符合Flutter的生命周期规则。
3. 优化状态监听逻辑
使用Consumer监听Provider状态变化即可,无需在build中重复调用Provider.of。
修改后的完整代码
class AdressenWidget extends StatefulWidget { const AdressenWidget({Key? key}) : super(key: key); @override State<AdressenWidget> createState() => _AdressenWidgetState(); } class _AdressenWidgetState extends State<AdressenWidget> { String _heading = ''; String _name = ''; String _address = ''; String _telefon = ''; String _email = ''; bool _isChecked = false; @override void initState() { super.initState(); _initializeAllData(); } Future<void> _initializeAllData() async { // 仅初始化一次Provider final provider = locator<EAProvider>(); await provider.initialize(); // 初始化本地状态 _updateLocalState(provider.addressList); } void _updateLocalState(List<Addressobject> addressList) { if (addressList.isNotEmpty) { final adress = getData(addressList, list[0]); setState(() { _heading = adress.heading; _name = adress.name; _address = adress.address; _telefon = adress.telefon; _email = adress.email; _isChecked = adress.isChecked; }); } } @override Widget build(BuildContext context) { return Consumer<EAProvider>( builder: (context, v, child) => Container( margin: const EdgeInsets.fromLTRB(10, 5, 10, 5), padding: const EdgeInsets.fromLTRB(15, 10, 15, 10), decoration: auftragBox, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Visibility( visible: v.expandAdrWidget, child: SizedBox( child: mainBody(v.addressList, v.isDashboard), ), ) ]), ), ); } Widget mainBody(List<Addressobject> addressList, bool isExpanded) { return Column( children: [ IntrinsicHeight( child: Row( children: [ SizedBox( height: 170, child: Column( children: [ for (var i = 0; i < 6; i++) InkWell( onTap: () { changeState(addressList, i); }, child: const Icon( Icons.location_pin, color: Colors.black, size: 20.0, ), ), ], ), ), ], ), ) ], ); } void changeState(List<Addressobject> addressList, int index) { final adress = getData(addressList, list[index]); setState(() { _heading = adress.heading; _name = adress.name; _address = adress.address; _telefon = adress.telefon; _email = adress.email; _isChecked = adress.isChecked; }); } } // Provider侧的initialize方法保持不变 // void initialize() async { // addressList = address_model.fromJson(addressjson).addressobject!; // notifyListeners(); // }
额外说明
- 初始化逻辑移到
initState的异步方法中,确保仅执行一次,避免构建循环中触发状态更新。 - 通过
_updateLocalState方法封装本地状态初始化,用setState保证状态变更符合生命周期规则。 - 移除了
build中冗余的Provider.of调用,仅保留Consumer监听状态变化。
内容的提问来源于stack exchange,提问作者Salman Akbar
相关产品推荐
相关产品推荐

