setState()如何重建子窗口小部件?

问题描述 投票:0回答:2

我只需要了解一下当调用setState()时,有状态的小部件是如何构建有状态子元素的。请看下面的代码。

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();
  }
}

按下RaisedButton时

输出1 //仅保留StatefulChild()

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

输出2 //仅保留statefulChild

I/flutter ( 2903): Parent build method invoked

这有什么区别?引擎盖下会发生什么?非常感谢详细的解释。

dart flutter widget
2个回答
1
投票

当窗口小部件树重建时,Flutter使用==比较build方法返回的上一个窗口小部件和新窗口小部件。

在这种情况下有两种情况:

  • ==false。在这种情况下,Flutter将比较runtimeTypekey以了解是否应该保留先前小部件的状态。然后Flutter在那个小部件上调用build
  • ==true。在这种情况下,Flutter中止小部件树的构建(也就是不会调用build)。

由于小部件的不变性,这是一种可能的优化。

由于小部件是不可变的,如果==没有改变那么它意味着没有什么可以更新。因此,颤动可以安全地优化它。


0
投票

当你使用setState(())时,只会调用build()。现在在这个方法中你再次调用StatefulChild()(第一行)进一步实例化这个类,这样就可以执行这个类的build()方法。

但是当你使用statefulChild时,它并没有创建一个新实例,因为

StatefulChild statefulChild = StatefulChild();

build()方法之外使用。所以它只被召唤一次。

© www.soinside.com 2019 - 2024. All rights reserved.