有状态与无状态的区别如何影响何时重建小部件?
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
状态 class 中的字符串 data
会在 MainApp
构建时传递给 MainApp
StatelessWidget。然后以类似的方式将信息传递给 Level2
StatelessWidget 和 Level3
StatefulWidget。
当Level3
中的TextField
变化时,触发setTextField
。 setTextField
在 MyApp
中定义,我认为当字符串 data
发生变化时(在 setState()
内)它应该触发重建 all 受更改影响的小部件。
MainApp
小部件 (appBar) 中的文本发生变化,显示 MainApp
已按照我的预期重建。但是 Level3
小部件没有任何反应;它没有重建。 createState()
方法中的 print 语句不执行,Text 小部件的文本不改变。
为什么 Level3
StatefulWidget 不重建?
据我了解,状态小部件 Level3 已在树中的给定位置创建。
而根据stateful widget的契约,
小部件实施者有责任确保在此类状态更改时及时通知状态,使用 State.setState。
因此,在您的情况下,您需要在 level3 中设置 setstate 才能再次收到更改通知。
重建只发生在级别 1,因为 setState 被调用。
重建过程递归地继续,直到用户界面的描述完全具体。
在级别 3 中,class 有自己的一组字段
字符串级别 3 数据;
函数设置文本字段;
这意味着这些需要使用 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),
],
);
}
}
我想了解状态和提升状态在 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
状态 class 中的字符串 data
会在 MainApp
构建时传递给 MainApp
StatelessWidget。然后以类似的方式将信息传递给 Level2
StatelessWidget 和 Level3
StatefulWidget。
当Level3
中的TextField
变化时,触发setTextField
。 setTextField
在 MyApp
中定义,我认为当字符串 data
发生变化时(在 setState()
内)它应该触发重建 all 受更改影响的小部件。
MainApp
小部件 (appBar) 中的文本发生变化,显示 MainApp
已按照我的预期重建。但是 Level3
小部件没有任何反应;它没有重建。 createState()
方法中的 print 语句不执行,Text 小部件的文本不改变。
为什么 Level3
StatefulWidget 不重建?
据我了解,状态小部件 Level3 已在树中的给定位置创建。 而根据stateful widget的契约, 小部件实施者有责任确保在此类状态更改时及时通知状态,使用 State.setState。 因此,在您的情况下,您需要在 level3 中设置 setstate 才能再次收到更改通知。 重建只发生在级别 1,因为 setState 被调用。
重建过程递归地继续,直到用户界面的描述完全具体。 在级别 3 中,class 有自己的一组字段 字符串级别 3 数据; 函数设置文本字段; 这意味着这些需要使用 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),
],
);
}
}