In the following code, when the button is clicked, why can't [print("BBB's build function.")] be called? In the following code, when the button is clicked, why can't [print("BBB's build function.")] be called? dart dart

In the following code, when the button is clicked, why can't [print("BBB's build function.")] be called?


child: AAA( child: BBB(), ),

AAA() class takes a widget in the constructor, in your code you are passing BBB() widget. When you first run this code you will get:

AAA's build function.BBB's build function.

Since both classes are getting built. Now the FlatButton is inside the class AAA when you click it, setState() is called and setState() will call the build() method of the class AAA thus you get in the console when clicking:

AAA's build function.


Because every time you return the same child. (which is already built)

If you want to make a Build function called every time you need to use LayoutBuilder.

Check my codepen with your code and my changes

Codepen

    import 'package:flutter/material.dart';void main() {  runApp(    MaterialApp(      home: MyTest(),    ),  );}class MyTest extends StatelessWidget {  @override  Widget build(BuildContext context) {    return MaterialApp(      home: Scaffold(        body: Center(          child: AAA(            child: (context) => BBB(),          ),        ),      ),    );  }}class AAA extends StatefulWidget {  AAA({Key key, @required this.child}) : super(key: key);  final Widget Function(BuildContext) child;  @override  _AAAState createState() => _AAAState();}class _AAAState extends State<AAA> {  @override  Widget build(BuildContext context) {    print("AAA's build function.");    return FlatButton(        onPressed: () {          setState(() {});        },        child: LayoutBuilder(builder: (context, constrains) => widget.child(context)));  }}class BBB extends StatefulWidget {  @override  _BBBState createState() => _BBBState();}class _BBBState extends State<BBB> {  static int p = 0;  @override  Widget build(BuildContext context) {    p++;    return Text("text$p");  }}


I believe it's because Flutter optimizes the rebuilding of widgets. In other words, after you press the FlatButton and setState gets called, Flutter rebuilds AAA because you explicitly asked for it (by calling setState).

After that, Flutter will also look to rebuild all of AAA's children. But before it does that, Flutter is smart enough to check whether it is worth rebuilding AAA's children. Flutter will compare the existing BBB widget, with the new BBB widget if it was rebuilt. If they are the same, flutter will abort the rebuild of BBB to save resources/optimize rebuilds.

In your case, they are the same. There's no difference between the return value of the existing BBB and the new BBB. It's always Text("text"). Your print(bbb...) line is not returned by the function. It comes before the return statement.

Check out this answer from Remi (creator of Provider package) on more info about the topic.