我正在尝试在小部件初始化时设置一个提供程序变量,以便小部件具有适当的数据。执行此操作时出现错误。代码如下:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
builder: (context) => ListManager(),
child: MaterialApp(
title: 'crud-to-do',
home: Home(), // Home calls ListWidget()
),
);
}
}
class ListWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final listManager = Provider.of<ListManager>(context);
listManager.list = [
ListItem(title: 'myTtitle', description: 'My desc', id: '1324j323e')
];
if (listManager.list.isEmpty) return Text("hey");
return Text(listManager.list[0].title);
}
}
这有效,但我收到一个错误:
flutter: ══╡ EXCEPTION CAUGHT BY FOUNDATION LIBRARY ╞════════════════════════════════════════════════════════
flutter: The following assertion was thrown while dispatching notifications for ListManager:
flutter: setState() or markNeedsBuild() called during build.
flutter: This ChangeNotifierProvider<ListManager> widget cannot be marked as needing to build because the
flutter: framework is already in the process of building widgets. A widget can be marked as needing to be
flutter: built during the build phase only if one of its ancestors is currently building. This exception is
flutter: allowed because the framework builds parent widgets before children, which means a dirty descendant
flutter: will always be built. Otherwise, the framework might not visit this widget during this build phase.
flutter: The widget on which setState() or markNeedsBuild() was called was:
flutter: ChangeNotifierProvider<ListManager>
flutter: The widget which was currently being built when the offending call was made was:
flutter: ListWidget
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:3680
flutter: #1 Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:3695
flutter: #2 State.setState
因此,我尝试像这样对listManager.list
设置进行initState
:
@override
void initState() {
listManager.list = [
ListItem(title: 'myTtitle', description: 'My desc', id: '1324j323e')
];
}
但是我收到一个错误说:
声明"initState"未被引用。
在这两种情况下,我都做错了什么,设置provider
的正确方法是什么?
在生成方法中,使用Provider.of<ListManager>(context, listen: false)
来防止重新生成。
默认情况下,listen
设置为true
,并在模型更改时触发重新生成,这将在build()
方法或initState()
中引发异常。