Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

[New rule] avoid-unnecessary-setstate #332

Closed
@incendial

Description

@incendial

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'),
    );
  }
}

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions