Flutter全局investorList更新后Widget未重建的问题求助
问题描述
错误提示:
setState() called in constructor: InvestorState#5d7b8(lifecycle state: created, no widget, not mounted)
代码示例
import 'package:flutter/material.dart'; class Investor extends StatefulWidget { @override State<Investor> createState() => InvestorState(); } List<InvestorList> investorList = []; class InvestorState extends State<Investor> { List<InvestorList> investorLIST = []; void addInvestor({required String name, required int taka}) { final investor = InvestorList(investorName: name, investorTaka: taka); investorLIST.add(investor); setState(() {}); } List<Widget> widgetList() { List<Widget> widgetMakingList = []; setState(() { investorLIST; }); for (int i = 0; i < investorLIST.length; i++) { widgetMakingList.add(Column( children: <Widget>[ Text( '${investorLIST[i].investorName!}\n' 'investing amount:${investorLIST[i].investorTaka!} taka', style: const TextStyle( color: Colors.black87, fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: 'Times new Roman'), ), const SizedBox( height: 10, ), SizedBox( height: 5, child: Container( color: Colors.black87, ), ), ], )); } return widgetMakingList; } @override void initState() { super.initState(); setState(() { investorLIST = investorList; }); } @override Widget build(BuildContext context) { return SizedBox( height: 200, child: ListView( children: widgetList(), ), ); } } class InvestorList { final String investorName; final int investorTaka; InvestorList({required this.investorName, required this.investorTaka}); }
import 'package:flutter/material.dart'; class Investor extends StatefulWidget { @override State<Investor> createState() => _InvestorState(); } List<InvestorList> investorList = []; class _InvestorState extends State<Investor> { void addInvestor({required String name, required int taka}) { final investor = InvestorList(investorName: name, investorTaka: taka); investorList.add(investor); setState(() {}); } List<Widget> widgetList() { List<Widget> widgetMakingList = []; setState(() { investorList; }); for (int i = 0; i < investorList.length; i++) { widgetMakingList.add(Column( children: <Widget>[ Text( '${investorList[i].investorName!}\n' 'investing amount:${investorList[i].investorTaka!} taka', style: const TextStyle( color: Colors.black87, fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: 'Times new Roman'), ), const SizedBox( height: 10, ), SizedBox( height: 5, child: Container( color: Colors.black87, ), ), ], )); } return widgetMakingList; } @override void initState() { super.initState(); setState(() { investorList; }); } @override Widget build(BuildContext context) { return SizedBox( height: 200, child: ListView( children: widgetList(), ), ); } } class InvestorList { final String investorName; final int investorTaka; InvestorList({required this.investorName, required this.investorTaka}); }
需求与疑问
我希望全局变量investorList更新时,Investor组件能自动重建,但目前实现不了。我知道把investorList放到_InvestorState类内部能解决问题,但这个列表需要被其他类访问。我试过调用setState()但没用,该怎么处理?
解决方案
先修复当前代码中的错误
- 移除
initState里的无效setState:initState中调用setState会触发组件未挂载的错误,而且直接赋值不需要setState:@override void initState() { super.initState(); investorLIST = investorList; // 仅第一个版本代码需要,第二个版本直接用全局变量 } - 移除
widgetList里的setState:该方法用于生成组件列表,调用setState会导致无限重建循环,直接遍历列表即可。
核心问题:全局变量无法触发组件重建
普通全局列表更新后,Flutter不会自动通知组件刷新,因为组件无法感知变量变化。要实现跨组件共享状态并自动刷新,推荐以下两种方案:
方案一:使用ValueNotifier+ValueListenableBuilder(轻量原生方案)
- 将全局变量改为
ValueNotifier:final ValueNotifier<List<InvestorList>> investorList = ValueNotifier([]); - 修改
Investor组件,通过ValueListenableBuilder监听变化:class Investor extends StatelessWidget { void addInvestor({required String name, required int taka}) { final investor = InvestorList(investorName: name, investorTaka: taka); // 必须生成新列表触发监听,不能直接add(列表是引用类型) investorList.value = [...investorList.value, investor]; } @override Widget build(BuildContext context) { return SizedBox( height: 200, child: ValueListenableBuilder<List<InvestorList>>( valueListenable: investorList, builder: (context, list, child) { return ListView( children: list.map((item) { return Column( children: <Widget>[ Text( '${item.investorName}\n' 'investing amount:${item.investorTaka} taka', style: const TextStyle( color: Colors.black87, fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: 'Times new Roman'), ), const SizedBox(height: 10), SizedBox( height: 5, child: Container(color: Colors.black87), ), ], ); }).toList(), ); }, ), ); } } - 其他类操作列表:
- 读取:
investorList.value - 添加:
investorList.value = [...investorList.value, newItem];
- 读取:
方案二:使用ChangeNotifier+Provider(适合复杂场景)
- 添加依赖到
pubspec.yaml:dependencies: flutter: sdk: flutter provider: ^6.0.5 - 创建状态管理类:
import 'package:flutter/foundation.dart'; class InvestorModel extends ChangeNotifier { List<InvestorList> _investorList = []; List<InvestorList> get investorList => _investorList; void addInvestor(String name, int taka) { _investorList.add(InvestorList(investorName: name, investorTaka: taka)); notifyListeners(); // 通知所有监听组件刷新 } } - 在应用顶层注册Provider:
void main() { runApp( ChangeNotifierProvider( create: (context) => InvestorModel(), child: const MyApp(), ), ); } - 修改
Investor组件获取状态:class Investor extends StatelessWidget { @override Widget build(BuildContext context) { final investorModel = Provider.of<InvestorModel>(context); return SizedBox( height: 200, child: ListView( children: investorModel.investorList.map((item) { return Column( children: <Widget>[ Text( '${item.investorName}\n' 'investing amount:${item.investorTaka} taka', style: const TextStyle( color: Colors.black87, fontSize: 20.0, fontWeight: FontWeight.bold, fontFamily: 'Times new Roman'), ), const SizedBox(height: 10), SizedBox( height: 5, child: Container(color: Colors.black87), ), ], ); }).toList(), ), ); } } - 其他类操作列表:
Provider.of<InvestorModel>(context, listen: false).addInvestor('张三', 1000);
原setState无效原因
组件内部的setState仅能感知自身状态变量的变化,全局变量的修改组件无法感知。其他类修改全局变量时,Investor组件完全不知道变化,自然不会重建。上述状态管理方案通过监听机制,让组件能感知全局状态变化并自动重建。
内容的提问来源于stack exchange,提问作者Atik19
相关产品推荐
相关产品推荐

