Kathryn Newbould
Kathryn Newbould

Reputation: 63

Am not rebuilding objects on build() call

Despite flutter calling build (and printing the correct information as below), it doesn't seem to build new TaskWidgets (the print in TaskWidgetState's constructor is not called). This is creating some unusual behaviour in my application (for example, the persistence of deleted ListView items).

I have the following code:

class TaskWidget extends StatefulWidget {
  TaskWidget({this.task, this.callToSave, this.callToDelete});
  final Task task;
  final Function callToSave;
  final Function callToDelete;

  @override
  State<StatefulWidget> createState() {
    return new TaskWidgetState(task, callToSave, callToDelete);
  }
}

class TaskWidgetState extends State<TaskWidget>{
  Task task;
  Function toCallOnChange;
  Function callToDelete;

  TaskWidgetState(Task task, Function callToSave, Function callToDelete){
    print("I'm a task widget for " + task.serialise().toString());
    this.task = task;
    toCallOnChange = callToSave;
    this.callToDelete = callToDelete;
  }
}

and

class ToDoListWidget extends State<ToDoList>{
      List<Task> _toDo = new List<Task>();
       ...

@override
  Widget build(BuildContext context) {
  print("building");
    return new Scaffold(
      body: new ListView(
          children: <Widget> [
            generateCard(),
...
          ]
      ),
    );


  }


 Widget generateCard() {
        return new Card(
          child: new Column (
            children: generateWidgets()
          ),
          ...
        );
      }


  List<Widget> generateWidgets() {
    print("generating Widgets");
    List<Task> tasks = getTasks();
    List<Widget> widgets = new List<Widget>();
    print("I have " + tasks.length.toString() + " widgets to build");
    for(Task t in tasks) {
      print(t.title);
      TaskWidget widget = new TaskWidget(task: t, callToSave: saveList, callToDelete: deleteTask,);
      widgets.add(widget);
    }
    return widgets;
  }
}

Prints out:

building
I/flutter (28783): Returning for Daily
I/flutter (28783): // correct, undeleted task

but onscreen state doesn't reflect this

Upvotes: 0

Views: 41

Answers (1)

rmtmckenzie
rmtmckenzie

Reputation: 40433

You're not using State and Stateful Widget properly.

How it works in flutter is that the Widget can be created many times, but there will most likely only be one instance of a State to go along with it.

It's a bit of an anti-pattern to have a constructor for a state.

Instead you should be doing something like this:

class TaskWidget extends StatefulWidget {
  TaskWidget({this.task, this.callToSave, this.callToDelete});
  final Task task;
  final Function callToSave;
  final Function callToDelete;

  @override
  State<StatefulWidget> createState() => new TaskWidgetState();
}

class TaskWidgetState extends State<TaskWidget>{
   Widget build(Context context) {
     // you can just use the widget.task, this is to illustrate.
     var task = widget.task;
     var callToSave = widget.callToSave;
     var callToDelete = widget.calltoDelete;
   }
}

This way, when the widget changes, your state will be re-built and will use whatever the updated values are that were passed into the widget.

Upvotes: 1

Related Questions