如何在Flutter中使用提供程序正确获取API [英] How to correctly fetch APIs using Provider in Flutter
问题描述
我目前正在处理一个问题,我需要一些API中的数据才能将其显示在我的小部件中.我遵循了一些提供程序体系结构模式,其中两次setState:
I'm currently dealing with a problem where I need some data from an API to show it into my widgets. I've following some Provider architecture pattern, where you setState two times:
1-提取数据时
2-当数据已被提取
所以我当前要解决的问题是,我的小部件引发了以下错误:
So the problem I'm currently dealing is, my widget throws the following error:
setState() or markNeedsBuild() called during build.
我知道此错误是因为在构建过程中调用了setState,但是..如何在构建过程中获取我的api,然后将其显示给我的小部件?这是我的代码:
I know this error is because setState is called during build, but.. how can I fetch my api during build, and then show it to my widgets? Here is my code:
NewsPage.dart
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
SideBarWidget _sidebar;
@override
void initState() {
Provider.of<HomeViewModel>(context, listen: false)
.fetchUltimaNoticia(context); --> ****Data to get fetched****
_sidebar = const SideBarWidget();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('INICIO'),
centerTitle: true,
automaticallyImplyLeading: false,
leading: Builder(
builder: (context) => IconButton(
icon: const Icon(Icons.menu),
onPressed: () => Scaffold.of(context).openDrawer(),
),
),
),
drawer: _sidebar,
body: FormNoticiaContainer(),
);
}
}
FormContainer()
Widget build(BuildContext context) {
return _crearBodyNoticia(context);
}
Widget _crearBodyNoticia(context) {
final homeVm = Provider.of<HomeViewModel>(context, listen: true);
return homeVm.state == ViewState.Busy
? Center(child: CircularLoading())
: Center(
child: DataToShowWidget()
HomeViewModel.dart
class HomeViewModel extends BaseModel {
////////
//NOTICIAS
////////
NoticiaDB _noticia;
NoticiaDB get noticia => _noticia;
set setNoticia(NoticiaDB noticia) {
_noticia = noticia;
}
Future fetchUltimaNoticia(BuildContext context) async {
setState(ViewState.Busy);
var response = await noticiaProvider.obtenerNoticiaPublicada();
setNoticia = response;
setState(ViewState.Idle);
}
}
BaseModel
ViewState _state = ViewState.Idle;
ViewState get state => _state;
void setState(ViewState viewState) {
_state = viewState;
notifyListeners();
}
推荐答案
您可以使用WidgetsBinding.instance.addPostFrameCallback
有关详细信息,您可以参考 https://www.didierboelens.com/faq/week2/
You can use WidgetsBinding.instance.addPostFrameCallback
For detail, you can reference https://www.didierboelens.com/faq/week2/
代码段
@override
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_){
Provider.of<HomeViewModel>(context, listen: false)
.fetchUltimaNoticia(context);
});
}
这篇关于如何在Flutter中使用提供程序正确获取API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!