What does `setState` do, and what exactly happens when you call it?
Show answer — try answering out loud first
setState tells Flutter that a widget's internal state has changed and that it needs to rebuild. It marks the element as "dirty" and schedules a new call to build on the next frame. You should put the state change inside the setState callback, not outside.
When you change a state variable, Flutter doesn't detect it on its own. setState(() { ... }) does two things:
- It runs the code you pass to it (where you modify the state).
- It marks the widget as "needs to rebuild" so Flutter calls
buildagain and updates the screen.
It's the most basic way to manage state in Flutter. It works great for a widget's local state (a counter, whether a panel is open). For state shared across many widgets, it falls short, and it's better to use a state management solution.
import 'package:flutter/material.dart';
class Toggle extends StatefulWidget {
const Toggle({super.key});
@override
State<Toggle> createState() => _ToggleState();
}
class _ToggleState extends State<Toggle> {
bool _isOn = false;
@override
Widget build(BuildContext context) {
return SwitchListTile(
title: Text(_isOn ? "On" : "Off"),
value: _isOn,
onChanged: (newValue) {
setState(() {
_isOn = newValue; // the change goes INSIDE setState
});
},
);
}
}
Two frequent mistakes:
- Changing the state outside of
setState:_isOn = true;without wrapping it. The value changes but the UI doesn't update. - Calling
setStateduringbuildor after the widget has been unmounted. CallingsetStateafter anawaitwithout checkingmountedcan throw "setState() called after dispose()". The fix:if (mounted) setState(...).
"
setStatetells Flutter that the widget's state changed, marks the element as dirty, and schedules a rebuild withbuild. The state change has to go inside thesetStatecallback, otherwise the UI never finds out. I use it for a widget's local state, like a counter or a switch. For state shared across many widgets I prefer a solution like Provider or Riverpod, becausesetStateonly rebuilds that one widget."
What's the difference between these two lines inside a State?
_count++;
setState(() => _count++);
See answer
_count++; changes the value in memory but does not rebuild the UI: the screen will keep showing the old number until something else triggers a build. setState(() => _count++); changes the value and asks Flutter to rebuild, so the screen updates immediately.