繁体   English   中英

有状态与无状态的区别如何影响何时重建小部件?

[英]How does the stateful vs. stateless distinction affect when widgets will be rebuilt?

我想了解状态和提升状态在 Flutter 中是如何工作的。 在下面的代码中,我制作了一个简单的应用程序,我试图通过多个级别传递或提升一个字符串和一个函数。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String data = 'MyApp class data';

  void setTextField(String s) {
    setState(
      () {
        data = s;
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MainApp(data, setTextField),
    );
  }
}

class MainApp extends StatelessWidget {
  final String mainAppData;
  final Function setTextField;
  MainApp(this.mainAppData, this.setTextField);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(mainAppData)),
      body: Container(
        child: Level2(mainAppData, setTextField),
      ),
    );
  }
}

class Level2 extends StatelessWidget {
  final String level2Data;
  final Function setTextField;
  Level2(this.level2Data, this.setTextField);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Level3(level2Data, setTextField),
    );
  }
}

class Level3 extends StatefulWidget {
  final String level3Data;
  final Function setTextField;
  Level3(this.level3Data, this.setTextField);

  @override
  _Level3State createState() {
    print('Level3: $this.level3Data');
    return _Level3State(this.level3Data, this.setTextField);
  }
}

class _Level3State extends State<Level3> {
  String level3Data;
  Function setTextField;
  _Level3State(this.level3Data, this.setTextField);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        TextField(
          onChanged: setTextField,
        ),
        Text(level3Data),
      ],
    );
  }
}

当应用程序启动时, _MyAppState状态类中的字符串data会在构建MainApp时传递给MainApp StatelessWidget。 然后以类似的方式将信息传递给Level2 StatelessWidget 和Level3 StatefulWidget。

Level3中的TextField发生变化时,触发setTextField setTextField是在MyApp中定义的,我认为当 String data发生变化时(在setState()内部)它应该触发重建所有受变化影响的小部件。

MainApp小部件 (appBar) 中的文本发生变化,显示MainApp已按预期重建。 但是Level3小部件没有任何反应; 它没有重建。 createState()方法中的 print 语句不执行,Text 小部件的文本不改变。

为什么Level3 StatefulWidget 不重建?

据我所知,有状态的小部件 Level3 已经在树中的给定位置创建。 并且根据有状态小部件的契约,小部件实现者有责任确保在此类状态更改时及时通知 State,使用 State.setState。 因此,在您的情况下,您需要在 level3 中设置 setstate 才能再次收到更改通知。 重建只发生在级别 1,因为调用了 setState。

重建过程递归地继续,直到用户界面的描述完全具体。 在级别 3 中,该类有自己的一组字段 String level3Data; 函数设置文本字段; 这意味着这些需要使用 SetState 再次设置,或者如果您执行类似的操作,则小部件构建将继续。

class Level3 extends StatefulWidget {
  final String level3Data;
  final Function setTextField;
  Level3(this.level3Data, this.setTextField);

  @override
  _Level3State createState() {
    print('Level3: $this.level3Data');
    return _Level3State();
  }
}

class _Level3State extends State<Level3> {
  // String level3Data;
  // Function setTextField;

  @override
  Widget build(BuildContext _) {
    return Column(
      children: <Widget>[
        TextField(
          onChanged: widget.setTextField,
        ),
        Text(widget.level3Data),
      ],
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM