Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing setState causes Infinite Loop Flutter

I'm new to Flutter and I'm having state issue. If anyone could help me out I would greatly appreciate it.

So I'm initially setting the items of a Flutter drop-downmenu to a list, which we'll call List l And it's value too, which will call variable v.

Then at the beginning of the parent widget, before build, I call a method which gets some information from the sqlflite database. And when it returns, I create a new List of drop-downmenuItem and implement the new state. I set List l to the newly created and the value to the first value of the first item of the List, so that the drop-downmenu re-renders.

This seems to be working fine, except that the method which gets info from the database keeps getting called which causes an infinite loop. And freezes my app. Does anyone know what I'm doing wrong?

Thank you so much!

    // Declaring variables
    List<DropdownMenuItem> _classList;

    String _chosenClass;


    initState:

    @override

    void initState() {

     _classList = [DropdownMenuItem(

       child: Text("Choose Class"),

       value: null,)];

     _chosenClass = _classList.first.value;

     super.initState();

    }


    // Get info from sqlflite database: 

    getClassesToDisplay() {

     debugPrint("Works");

     getDatabaseInstances(tableClass, [className]).then((classNames){

       if(classNames.length > 0){

         List<DropdownMenuItem> tempList =[];

         classNames.forEach((classArg){

           tempList.add(

               DropdownMenuItem(

                 child: Text(classArg[className]),

                 value: classArg[className],

               )

           );

         });

         debugPrint("TEMPLIST: ${tempList}");

         setState(() {

           _classList = tempList;

           _chosenClass = tempList.first.value;

         });

       }


     });


    }


    // Build:

    @override

    Widget build(BuildContext context) {

     getClassesToDisplay();

     debugPrint("BLAHHHH");

     return new Scaffold(

       appBar: new AppBar(

         title: new Text("Your Classes"),

       ),

       body: Column(

         children: <Widget>[

           Container(

             margin: EdgeInsets.only(top: 10.0, left: 10.0),

             child: raisedButtonMaker("Tap to add a class", (){

               Navigator.pushNamed(context, '/add_seek');

             }, Theme.of(context).primaryColor, context)

           ,),

           DropdownButton(

             value: _chosenClass, //value of currently picked item

             items: _classList,

             onChanged: (value){ //update value of dropDown to what was just chosen

               setState(() {

                 _chosenClass = value;

               });

             },

           ),

         ],

       ),

     );

    }
like image 915
Prince Hodonou Avatar asked Jun 19 '18 20:06

Prince Hodonou


1 Answers

getClassesToDisplay() calls setState() with a delay (then) which causes build() to be run, which calls getClassesToDisplay() - simple endless loop.

Remove getClassesToDisplay() from build() and call it from initState() instead.

like image 189
Günter Zöchbauer Avatar answered Nov 03 '22 12:11

Günter Zöchbauer