Not so fast.. Let’s read the fine print:

Whenever you change the internal state of a State object, make the change in a function that you pass to setState.

So, we are supposed to wrap the changes to the widget’s state in that callback.

Wait a minute… Is that always possible?

As applications get more complex, it gets hard to contain the “state” of a widget. Your widget will start depending on layers of code you might not have any control over. These layers will have their own logic and manage their own state.

Oops! It seems like we just mentioned the word “state” outside the widget itself. How are we supposed to wrap that?

Enter the odd looking empty setState call.

class MyWidget ... { void initState() {

// Something changed in my data source

dataSource.listen(() {

setState(() {}); // Woot!

);

} Widget build() {

// Use my data source to build something

}

}

This is not just odd but dangerous. When we did an audit of our code, we found that 20% of the calls to setState were empty. We wanted to rebuild the widget for a non-obvious and non-localized reason, so we just sort of threw a setState in there.

class MyWidget ... { void handleClick() {

// Call some obscure fn in data source.

// Did that change anything? No idea.. So just in case:

setState(() {});

} Widget build() {

// Use my data source to build something

}

}

I mean, it worked but nobody really understood why. Cue the worst argument in software engineering ever:

“Well… It breaks if we take it out.”

This was not good. We were taking two hits at the same time: