Reputation: 131
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
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
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
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