[New rule] avoid-unnecessary-setstate #332
Description
Please describe what the rule should do:
As @GroovinChip pointed out in one of a twitter thread, calling setState
from a widget initState
or build
methods will lead to unnecessary rerender of the widget. It looks like a potential problem especially for new developers, so the idea of the rule is to warn about setState
invocations in initState
or build
.
We have not quite come to a conclusion, should we also consider calling sync methods from a widget initState
with setState
call in it bad or acceptable.
@GroovinChip thanks again for providing examples and sharing the idea.
Additional resources:
What category of rule is this? (place an "X" next to just one item)
[X] Warns about a potential error (problem)
[ ] Suggests an alternate way of doing something (suggestion)
[ ] Other (please specify:)
Provide 2-3 code examples that this rule will warn about (it will be better if you can provide both good and bad examples):
Bad:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
String myString = '';
@override
void initState() {
super.initState();
setState(() {
myString = "Hello";
}); // Bad
if (condition) {
setState(() {}); // Bad
}
}
@override
Widget build(BuildContext context) {
setState(() {
myString = "Hello";
}); // Bad
if (condition) {
setState(() {}); // Bad
}
return ElevatedButton(
child: Text('PRESS'),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
String myString = '';
@override
void initState() {
super.initState();
myMethod(); // Good or Bad ???
myAsyncMethod(); // Good
}
void myMethod() {
setState((){
myString = "Hello";
}); // Good
}
Future<void> myAsyncMethod() async {
final data = await service.fetchData();
setState(() {
myString = data;
});
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => myMethod(), // Good
child: Text('PRESS'),
);
}
}