我有一个Flutter页面,其中包含一个名为 VisitsHistory 的小部件,其中包含2个名为 VisitsList 和 Statistics
的子小部件>子窗口小部件“ VisitsList”具有一个流构建器,该流构建器从Firestore获取数据并呈现卡列表。
我希望来自streambuilder的数据流不断更新“统计”小部件。他们俩共享同一个父母(访问记录)。
我尝试使用Streambuilder的回调通知父对象,然后父对象调用SetState(),但这给了我一个错误:setState() or markNeedsBuild called during build
我理解该错误的原因是,我在streambuilder返回应该构建的内容之前进行了回调,但是我还能在其他地方放置该回调,以便确保构建已经完成并且可以安全进行在父级中调用setState()?
N.B .:我正在使用提供程序作为状态管理
这是VisitsList窗口小部件/ StreamBuilder中的摘录
class VisitsList extends StatelessWidget {
final Function getDebtDataCallback;
VisitsList(this.getDebtDataCallback);
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: doctorprovider.getVisitsHistory(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return new CircularProgressIndicator();
default:
if (snapshot.data.documents.isEmpty) {
return Text(
"No Visits yet",
style: TextStyle(color: Colors.white),
);
} else {
//CALLBACK IS HERE
getDebtDataCallback(snapshot);
return new ListView( ......
答案 0 :(得分:0)
可以使用值更新程序将值推入父级吗? Flutter团队创建了一个股票示例应用程序来演示此功能。
https://github.com/flutter/flutter/tree/master/examples/stocks
https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
在孩子中,您需要这个样板
class StockSettings extends StatefulWidget {
const StockSettings(this.configuration, this.updater);
final StockConfiguration configuration;
final ValueChanged<StockConfiguration> updater;
@override
StockSettingsState createState() => StockSettingsState();
}
class StockSettingsState extends State<StockSettings> {
void _handleBackupChanged(bool value) {
sendUpdates(widget.configuration.copyWith(backupMode: value ? BackupMode.enabled : BackupMode.disabled));
}
void sendUpdates(StockConfiguration value) {
if (widget.updater != null)
widget.updater(value);
}
在父级中,您传递了子级的配置更新程序,以调用父级的setState
。
class StocksAppState extends State<StocksApp> {
StockData stocks;
StockConfiguration _configuration = StockConfiguration(
stockMode: StockMode.optimistic,
backupMode: BackupMode.enabled,
debugShowGrid: false,
debugShowSizes: false,
debugShowBaselines: false,
debugShowLayers: false,
debugShowPointers: false,
debugShowRainbow: false,
showPerformanceOverlay: false,
showSemanticsDebugger: false
);
@override
void initState() {
super.initState();
stocks = StockData();
}
void configurationUpdater(StockConfiguration value) {
setState(() {
_configuration = value;
});
}
routes: <String, WidgetBuilder>{
'/': (BuildContext context) => StockHome(stocks, _configuration, configurationUpdater),
'/settings': (BuildContext context) => StockSettings(_configuration, configurationUpdater)
},