Maxime Barber
Maxime Barber

Reputation: 131

setState is not updating value

Problem: setState is not saving the value of _products.

Tried: If I print the value of _products inside the setState function, it is updated:

['Product 1', 'Product 2', 'New Product']

But when I pass _products to my Products class, the value of _products is reset:

['Product 1', 'Product 2']

Code:

import 'package:flutter/material.dart';

import './products.dart';

class ProductManager extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _ProductManagerState();
  }
}

class _ProductManagerState extends State<ProductManager> {
  @override
  Widget build(BuildContext context) {

    List<String> _products = ['Product 1', 'Product 2'];
    return Column(
      children: [
        Container(
          margin: EdgeInsets.all(10.0),
          child: RaisedButton(
            onPressed: () {
              setState(() {
                _products.add('New Product');
              });
            },
            child: Text('Add Product'),
          ),
        ),
        Products(_products),
      ],
    );
  }
}

Upvotes: 3

Views: 7757

Answers (3)

0xCCY
0xCCY

Reputation: 555

One golden rule to keep in mind while writing Flutter apps:

Widgets are immutable.

That meaning, anything declare inside a Widget (Stateful or Stateless) will not change after being build the very first time.

The state object (i.e. _ProductManagerState) while mutable, will not reflect any changes in the Widget (Golden Rule One).

Updates will only be reflected, if and if only if the widget is being rebuilt (note: rebuilding of widget =/= rebuilding of class!). Thus, when calling setState, it does not only add the product to the list but also forced a rebuild. This is why setState is needed at the first place.

Hence as others suggested, moving the initialization of _products out of the build will solve the problem of it not "saving".

It does save, just that it got re-initialize every time the widget re-build itself.

Upvotes: 7

satish
satish

Reputation: 1374

import 'package:flutter/material.dart';

import './products.dart';

class ProductManager extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _ProductManagerState();
  }
}

class _ProductManagerState extends State<ProductManager> {

  List<String> _products = ['Product 1', 'Product 2'];
  @override
  Widget build(BuildContext context) {

    return Column(
      children: [
        Container(
          margin: EdgeInsets.all(10.0),
          child: RaisedButton(
            onPressed: () {
              setState(() {
                _products.add('New Product');
              });
            },
            child: Text('Add Product'),
          ),
        ),
        Products(_products),
      ],
    );
  }
}

Upvotes: 0

bytesizedwizard
bytesizedwizard

Reputation: 6033

Initialize the _products list outside the build function.

Every time you call setState(), the build() method is called which resets _products since it's initialized inside the method.

Try doing this:

class _ProductManagerState extends State<ProductManager> {

  List<String> _products = ['Product 1', 'Product 2'];

  @override
  Widget build(BuildContext context) {
   /*Rest of the code*/
  }
}

Upvotes: 18

Related Questions