Home > Mobile >  Why is setState not working as I expected?
Why is setState not working as I expected?

Time:01-10

I already used a stateful widget, but it seems that the item wont display when pressing add.

final TextEditingController _commentController = TextEditingController();
List<String> _genComments = [
    'comment 1',
    'comment 2',
    'comment 3',
    'comment 4',
    'comment 5'
];

Here's my code in a ListView where the items are displayed:

Expanded(
child: Container(
  width: double.infinity,
  child: ListView.builder(
    itemCount: _genComments.length,
    itemBuilder: (context, index) {
      return Container(
        width: double.infinity,
        height: 100,
        child: Card(
          color: Colors.white,
          elevation: 5,
          child: Text(_genComments[index]),
        ),
      );
    },
  ),
),
),

Here's my code in button where I use setState:

child: ElevatedButton(
onPressed: () {
  setState(() {
    _genComments.add(_commentController.text);
  });
  _commentController.clear();
},

CodePudding user response:

You can use this code to get add a new element in listview

 TextEditingController commentController = TextEditingController();

     List<String> getComments = [
    'comment 1',
    'comment 2',
    'comment 3',
    'comment 4',
    'comment 5'
     ];
    
     void addItemToList(){
        setState(() {
          getComments.add(commentController.text);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(20),
                child: TextField(
                  controller: commentController,
                ),
              ),
              RaisedButton(
                child: Text('Add'),
                onPressed: () {
                  addItemToList();
                },
              ),
              Expanded(
                child: ListView.builder(
                  padding: const EdgeInsets.all(8),
                  itemCount: getComments.length,
                  itemBuilder: (context, index) {
                      return Container(
                        width: double.infinity,
                        height: 100,
                        child: Card(
                          color: Colors.white,
                          elevation: 5,
                          child: Text(getComments[index].toString()),
                        ),
                      );
                    },
                )
              )
            ]
          )
        );
      }
    }

CodePudding user response:

when you call setState it will call the build mehtod. which means all widget inside this mehtod will re-executed.

 Widget build(BuildContext context) {
        return Scaffold(

common mistake is, people declare their variable inside build method. and this cause the state variable will not updated. because everytime they call setState the value is re-declared to initial value. example:

  • Wrong
 Widget build(BuildContext context) {
  final TextEditingController _commentController = TextEditingController();
  List<String> _genComments = [
    'comment 1',
    ....
    ];

    return Scaffold(

  • Correct:

declare the state variable outside build method.

  final TextEditingController _commentController = TextEditingController();
  List<String> _genComments = [
    'comment 1',
    .....
    ];

Widget build(BuildContext context) {
    return Scaffold(

so, when you call the setState will update the value to the variable.

  • Related