skip to Main Content

I am not sure exactly when setState triggers the rebuild in Flutter.

I have some text on a screen that I update with setState. It rebuilds nicely. Here is the code:

setState(() {
 futureWait = "$fifteen second wait for both futures completed";
});

So I wanted to change the color of the text as well so I made a Boolean that I set after the setState function. I did that like this:

setState(() {
 futureWait = "$fifteen second wait for both futures completed";
});
futureWaitBool = true;

The widget looks like this:

  myText(futureWait, 15,
        !futureWaitBool ? Colors.white : Colors.green),

It works fine for now – but I wondered if I created a race condition. Is there are race condition if I do this?

setState(() {
 futureWait = "$fifteen second wait for both futures completed";
 futureWaitBool = true;
});

I can easily use the Boolean to switch the color and string and in that sense make it atomic. But I am really asking how it works and where is it documented. The existing documentation is unclear in my opinion.

For example the documentation says: "Calling setState notifies the framework that the internal state of this object has changed … which causes the framework to schedule a build for this State object." The documentation is written as if just the fact that you call it sets in motion the notification to the framework. I want to know does it happen when
a) you first call it;
b) you actually change a state variable in the callback;
c) when setState completes;
d) or some other time.

Thanks in advance.

3

Answers


  1. In Flutter, the setState method triggers a rebuild of the widget subtree. The setState method schedules a callback that updates the UI and re-runs the build method, but it doesn’t block further code execution.
    So, your initial approach does create a potential race condition because the boolean assignment after setState happens asynchronously. The updated code should indeed be inside the setState function to ensure all changes occur atomically, without race conditions.

    This ensures that both futureWait and futureWaitBool are updated together, guaranteeing no race conditions and consistent state.

    Login or Signup to reply.
  2. Here’s how setState method works:

    • large part of its work is a (validation checking) just checks whether this method is called to rebuild a state object that’s already disposed or not to generate an error if it was disposed.

    • check if the provided callback (parameter of the setState method) is asynchronous or not, if it’s an asynchronous it produces an error.

    after these validation operation done, this is a valid call

    • changes the element associated with that state object in the element tree.

    • finally, the framework calls the build method within that state object (rebuild).

    So, what about the race conditions you have mentioned?

    in either cases there’s no race condition.

    Look, the variable named futureWaitBoolean in such case is called a control variable because the UI elements depends on it to decide which color or text to visualize to user (so it controls what’s appeared to user).

    such type of variable should be modified within the setState method to guarantee it’s updated before rebuild.

    Note: if you didn’t modified it within the setState the build method will be called again but may be with the same UI with no change (since control variables have not changed yet).

    For more about setState

    Login or Signup to reply.
  3. I find Craig’s talks at Flutter Vikings Lifecycle of a Widget and Lifecycle of a renderObject to be invaluable, and I go back to rewatch them freqently. They make clear how build() works and what setState is doing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search