Flutter 在FutureBuilder中设置提供程序值
我有一个小部件,它向返回地图的api发出请求。我想做的不是每次加载小部件时都发出相同的请求,并将列表保存到Flutter 在FutureBuilder中设置提供程序值,flutter,dart,flutter-provider,Flutter,Dart,Flutter Provider,我有一个小部件,它向返回地图的api发出请求。我想做的不是每次加载小部件时都发出相同的请求,并将列表保存到appState.myList。但是当我这样做时,appState.myList=snapshot.data在FutureBuilder中,我得到以下错误: 颤振:══╡ 基金会例外╞════════════════════════════════════════════════════════ 颤振:在为MySchedule发送通知时引发了以下断言: 颤振:在生成过程中调用setState
appState.myList
。但是当我这样做时,appState.myList=snapshot.data
在FutureBuilder
中,我得到以下错误:
颤振:══╡ 基金会例外╞════════════════════════════════════════════════════════
颤振:在为MySchedule发送通知时引发了以下断言:
颤振:在生成过程中调用setState()或markNeedsBuild()。
颤振:无法将此ChangeNotifierProvider小部件标记为需要生成,因为
颤振:框架已经在构建小部件的过程中。可以将小部件标记为需要
颤振:仅当其祖先之一当前正在建造时,才在建造阶段建造。。。
sun.dart
文件:
class-Sun扩展了无状态小部件{
小部件构建(构建上下文){
final appState=Provider.of(上下文);
var db=PostDB();
小部件列表构建(appState){
最终列表=appState.myList;
返回ListView.builder(
itemCount:list.length,
itemBuilder:(上下文,索引){
返回ListTile(标题:Text(列表[index].title));
},
);
}
Widget futureBuild(appState){
回归未来建设者(
future:db.getPosts(),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
//appState.myList=snapshot.data;
返回ListView.builder(
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引){
返回ListTile(标题:Text(snapshot.data[index].title));
},
);
}else if(snapshot.hasrerror){
返回文本(“${snapshot.error}”);
}
返回中心(
子对象:CircularProgressIndicator(),
);
},
);
}
返回脚手架(
正文:appState.myList!=null
?列表构建(appState)
:futureBuild(appState));
}
}
postService.dart
文件:
class PostDB{
var isLoading=false;
Future getPosts()异步{
isLoading=true;
最后答复=
等待http.get(“https://jsonplaceholder.typicode.com/posts");
如果(response.statusCode==200){
isLoading=false;
返回(json.decode(response.body)作为列表)
.map((数据)=>Postmodel.fromJson(数据))
.toList();
}否则{
抛出异常(“加载帖子失败”);
}
}
}
我知道myList
调用notifyListeners()
,这就是导致错误的原因。希望我没弄错。如果是这样,我如何设置appState.myList并在应用程序中使用而不出现上述错误
导入“包:flift/foundation.dart”;
导入“包:myflatter/models/post model.dart”;
使用ChangeNotifier类MySchedule{
列表(myList),;
List get myList=>\u myList;
设置myList(列出新值){
_myList=新值;
notifyListeners();
}
}
出现该异常是因为您正在同步修改来自其子体的小部件
这是不好的,因为它可能导致不一致的小部件树。一些小部件。可能是使用变异前的值构建小部件,而其他小部件可能使用变异后的值
解决方法是消除不一致性。使用ChangeNotifierProvider
,通常有两种情况:
- 在
上执行的变异总是在创建changennotifier
的版本内执行 在这种情况下,您可以直接从changennotifier
变更通知程序的构造函数执行调用:
将MyNotifier与ChangeNotifier一起分类{ MyNotifier(){ //TODO:启动一些请求 } }
- 执行的更改可能会“延迟”进行(通常在更改页面之后)
在这种情况下,您应该在
或addPostFrameCallback
Future中将您的突变包装起来
类示例扩展了StatefulWidget{ @凌驾 _ExampleState createState()=>\u ExampleState(); } 类_示例状态扩展状态{ MyNotifier通知程序; @凌驾 void didChangeDependencies(){ super.didChangeDependencies(); final notifier=Provider.of(上下文); if(this.notifier!=通知程序){ this.notifier=通知程序; Future.microtask(()=>notifier.doSomeHttpCall()); } } @凌驾 小部件构建(构建上下文){ 返回容器(); } }
WidgetsBinding.instance.addPostFrameCallback()
。只需删除notifyListeners()代码>来自代码。我遇到了这个错误,这就是我解决问题所做的。您在哪里使用setter formyList
?在FutureBuilder中<代码>如果(snapshot.hasData){//appState.myList=snapshot.data;
为什么不在getPosts
中呢?是的……那会更好……但是我能拥有final appState=Provider.of(上下文)吗
在那里?我没有上下文…我从来没有真正理解上下文
的作用。我是个新手。请发布一个答案。我不知道,我没有提供者
类的经验。这个解决方案很好。我以为OP只想加载一次。在这种情况下,变更通知者
似乎不合适并使用Future.microtask
从build
中退出调用setState