首页 > 解决方案 > setState() 如何重建子部件?

问题描述

我只需要一些关于在调用 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

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

标签: dartflutterwidget

解决方案


当 widget 树重建时,Flutter 会使用==build方法返回的前一个和新的 widget 进行比较。

这种情况有两种情况:

  • ==false。在这种情况下,Flutter 将比较runtimeType&key以了解是否应该保留前一个小部件的状态。然后 Flutter 调用build该小部件

  • ==true。在这种情况下,Flutter 会中止构建小部件树(也不会调用build)。

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

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


推荐阅读