Skip to content

prefer_single_setstate

v0.4.0 Warning Fix Code Quality

Flags methods in State subclasses that contain multiple setState() calls at the same scope level. Each setState() call schedules a rebuild, so calling it multiple times in the same synchronous method triggers redundant rebuilds that can be avoided by merging all state mutations into a single call.

Multiple setState() calls in the same method cause Flutter to schedule multiple rebuilds in the same frame. While Flutter coalesces them into one actual rebuild, the pattern is misleading and fragile. Merging mutations into a single setState() makes the code clearer and avoids accidental intermediate states if the framework behavior changes.

See also: State.setState()

class _BadState extends State<BadWidget> {
String _a = '';
String _b = '';
void _update() {
setState(() {
_a = 'Hello';
});
setState(() {
_b = 'World';
});
}
// Even with code in between:
void _updateWithGap() {
setState(() {
_a = 'Hello';
});
debugPrint('between');
setState(() {
_b = 'World';
});
}
}
class _GoodState extends State<GoodWidget> {
String _a = '';
String _b = '';
void _update() {
setState(() {
_a = 'Hello';
_b = 'World';
});
}
}
// setState in separate closures is fine (different scopes):
void _setup() {
final callback1 = () {
setState(() { _data = 'a'; });
};
final callback2 = () {
setState(() { _data = 'b'; });
};
}
// setState in different methods is fine:
void _update1() {
setState(() { _data = 'Hello'; });
}
void _update2() {
setState(() { _data = 'World'; });
}

To disable this rule:

plugins:
many_lints:
diagnostics:
prefer_single_setstate: false