【发布时间】:2020-05-26 09:29:25
【问题描述】:
我目前正在处理一个问题,我需要来自 API 的一些数据才能将其显示到我的小部件中。我遵循了一些 Provider 架构模式,您在其中 setState 两次:
1- 获取数据时
2- 当数据已经被获取时
所以我目前正在处理的问题是,我的小部件抛出以下错误:
setState() or markNeedsBuild() called during build.
我知道这个错误是因为在构建过程中调用了 setState,但是.. 如何在构建过程中获取我的 api,然后将其显示给我的小部件?这是我的代码:
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);
}
}
基础模型
ViewState _state = ViewState.Idle;
ViewState get state => _state;
void setState(ViewState viewState) {
_state = viewState;
notifyListeners();
}
【问题讨论】:
-
您在
build期间不获取。使用FutureBuilder。见stackoverflow.com/a/60141803/7034640 -
同理,如果我使用 FutureBuilder 获取,setState 将再次被调用,问题将是相同的..
-
不一样。错误不会发生。
-
我的意思是是的,因为如果我将 API 的 fetch 放在 future builder 中,那么循环将是:Futurebuilder -> Builds -> Fetch Api inside futurebuilder(Which setState) -> 然后再次重建 - > 调用futurebuilder -> ......再次进行相同的循环
-
如果您打算继续使用
HomeViewModel方法,请使用包提供商的Consumer而不是Provider.of。
标签: flutter setstate flutter-provider