web-dev-qa-db-fra.com

Comment chercher correctement les API à l'aide d'un fournisseur en flutter

Je traite actuellement un problème dans lequel j'ai besoin de données d'une API pour le montrer dans mes widgets. J'ai suivi un modèle d'architecture des fournisseurs, où vous êtes installé deux fois:

1- lorsque les données sont récupérées

2- lorsque les données sont déjà récupérées

Donc, le problème que je traite actuellement est, mon widget jette l'erreur suivante:

setState() or markNeedsBuild() called during build.

Je sais que cette erreur est que SetState est appelée pendant la construction, mais .. Comment puis-je récupérer mon API pendant la construction, puis le montrer à mes widgets? Voici mon 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();
  }
4
Nikssj_

Vous pouvez utiliser WidgetsBinding.instance.addPostFrameCallback
Pour les détails, vous pouvez faire référence https://www.didierboelens.com/faq/week2/

extrait de code

@override
void initState(){
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_){
    Provider.of<HomeViewModel>(context, listen: false)
    .fetchUltimaNoticia(context);  

  });
}
4
chunhunghan