Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does setState() rebuild child widgets?

I just need some idea on how flutter stateful widgets build their stateful children when setState() is invoked. Please look at the code below.

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  Widget build(BuildContext context) {
    print("Parent build method invoked");
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            StatefulChild(), // Keeping this line gives the output 1
            statefulChild, // Keeping this line gives the output 2
            RaisedButton(
              child: Text('Click me'),
              onPressed: () {
                setState(() {});
              },
            )
          ],
        ),
      ),
    );
  }

  StatefulChild statefulChild = StatefulChild();
}

class StatefulChild extends StatefulWidget {
  StatefulChildState createState() => StatefulChildState();
}

class StatefulChildState extends State<StatefulChild> {
  @override
  Widget build(BuildContext context) {
    print("Child00 build method invoked");
    return Container();
  }
}

When the RaisedButton is pressed,

Output 1 // Keeping only StatefulChild(),

I/flutter ( 2903): Parent build method invoked
I/flutter ( 2903): Child00 build method invoked

Output 2 // Keeping only statefulChild,

I/flutter ( 2903): Parent build method invoked

What is the difference here? What happens under the hood? Detailed explanation is much appreciated.

like image 493
Iresh Dissanayaka Avatar asked Apr 09 '19 12:04

Iresh Dissanayaka


Video Answer


1 Answers

When the widget tree rebuilds, Flutter compares using == the previous and new widget returned by the build method.

There are two scenarios in that situation:

  • == is false. In that case, Flutter will compare the runtimeType & key to know if the state of the previous widget should be preserved. Then Flutter calls build on that widget

  • == is true. In which case, Flutter aborts the building of the widget tree (aka won't call build).

This is an optimization possible thanks to the immutability of widgets.

Since widgets are immutable, if == haven't changed then it means that there's nothing to update. Flutter can therefore safely optimize that.

like image 197
Rémi Rousselet Avatar answered Oct 10 '22 06:10

Rémi Rousselet