Flutter - SetState 不适用于提取的小部件
Flutter - SetState not working on extracted widgets
你好,基本上我想知道为什么 setState() 适用于提取为方法的小部件,但不适用于提取为小部件的小部件....
以及何时使用提取的小部件/提取的小部件作为方法,或者它们是否相同?但我想它们不可能是一样的,因为一个有效而另一个无效?
如果您想要我在将其更改为提取方法之前尝试过的代码:
来自主要 class:
void refresh() => setState(() {});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.blue,
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const [
SizedBox(height: 50),
PageHeader(),
PageBody(),
],
),
floatingActionButton: AddTaskButton(
transitionAnimationController: transitionAnimationController,
refresh: refresh,
),
),
);
}
提取的小部件:
class PageHeader extends StatelessWidget {
const PageHeader({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
color: Colors.blue,
size: 30,
),
),
const SizedBox(
height: 15,
),
const Text(
'Todoey',
style: TextStyle(color: Colors.white, fontSize: 35),
),
Text(
' ${TaskData.tasks.length} Tasks',
style: const TextStyle(color: Colors.white, fontSize: 15),
),
],
),
),
);
}
}
class PageBody extends StatelessWidget {
const PageBody({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded(
flex: 3,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TaskList(taskData: TaskData.tasks),
),
),
);
}
}
提取的方法:
Expanded pageHeader() {
return Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
color: Colors.blue,
size: 30,
),
),
const SizedBox(
height: 15,
),
const Text(
'Todoey',
style: TextStyle(color: Colors.white, fontSize: 35),
),
Text(
' ${TaskData.tasks.length} Tasks',
style: const TextStyle(color: Colors.white, fontSize: 15),
),
],
),
),
);
}
}
Expanded pageBody() {
return Expanded(
flex: 3,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TaskList(taskData: TaskData.tasks),
),
),
);
}
您提取的小部件是无状态 小部件。
setState() 仅适用于 有状态 小部件。
为了获得更好的性能,使用提取的小部件比使用提取的方法更好。
setState()
其实并不关心是不是提取widget的och方法。它没有对此进行“检查”。
它告诉 UI 小部件的状态已更改,可能需要重绘。它安排了一个新的构建。但如果它没有 to.
,它不一定会重绘所有内容
因此,根据 parent 小部件(调用 setState)下方的小部件类型及其包含的内容,它们可能会被重绘。
但是,重绘时总是调用一个方法(“通过方法提取小部件”),非常un-efficient。这就是为什么您可能会观察到差异。
观看此视频以了解有关差异的更多信息:
https://www.youtube.com/watch?v=IOyq-eTRhvo
根据经验,“始终”提取小部件,而不是通过方法创建小部件。
为什么您的 child 小部件没有重建可能是多种原因之一。无论哪种方式,我认为它与本例中的 parents setState() 调用没有任何关系。
child 小部件没有任何理由重建。您似乎正在通过一些全局变量(?)TaskData.tasks...添加内容? child 小部件不会“观察”该变量的变化。所以他们没有重建的理由。
如果您从 parent 注入数据,使用一些状态管理,如 Bloc,或使用 Provider 或 ChangeNotifier 或类似的,用于 PageHeader()、PageBody() 及其 children 建立他们的基础,然后一切都会相应地更新。
你好,基本上我想知道为什么 setState() 适用于提取为方法的小部件,但不适用于提取为小部件的小部件....
以及何时使用提取的小部件/提取的小部件作为方法,或者它们是否相同?但我想它们不可能是一样的,因为一个有效而另一个无效?
如果您想要我在将其更改为提取方法之前尝试过的代码:
来自主要 class:
void refresh() => setState(() {});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.blue,
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const [
SizedBox(height: 50),
PageHeader(),
PageBody(),
],
),
floatingActionButton: AddTaskButton(
transitionAnimationController: transitionAnimationController,
refresh: refresh,
),
),
);
}
提取的小部件:
class PageHeader extends StatelessWidget {
const PageHeader({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
color: Colors.blue,
size: 30,
),
),
const SizedBox(
height: 15,
),
const Text(
'Todoey',
style: TextStyle(color: Colors.white, fontSize: 35),
),
Text(
' ${TaskData.tasks.length} Tasks',
style: const TextStyle(color: Colors.white, fontSize: 15),
),
],
),
),
);
}
}
class PageBody extends StatelessWidget {
const PageBody({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Expanded(
flex: 3,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TaskList(taskData: TaskData.tasks),
),
),
);
}
}
提取的方法:
Expanded pageHeader() {
return Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: Icon(
Icons.list,
color: Colors.blue,
size: 30,
),
),
const SizedBox(
height: 15,
),
const Text(
'Todoey',
style: TextStyle(color: Colors.white, fontSize: 35),
),
Text(
' ${TaskData.tasks.length} Tasks',
style: const TextStyle(color: Colors.white, fontSize: 15),
),
],
),
),
);
}
}
Expanded pageBody() {
return Expanded(
flex: 3,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TaskList(taskData: TaskData.tasks),
),
),
);
}
您提取的小部件是无状态 小部件。
setState() 仅适用于 有状态 小部件。
为了获得更好的性能,使用提取的小部件比使用提取的方法更好。
setState()
其实并不关心是不是提取widget的och方法。它没有对此进行“检查”。
它告诉 UI 小部件的状态已更改,可能需要重绘。它安排了一个新的构建。但如果它没有 to.
,它不一定会重绘所有内容因此,根据 parent 小部件(调用 setState)下方的小部件类型及其包含的内容,它们可能会被重绘。
但是,重绘时总是调用一个方法(“通过方法提取小部件”),非常un-efficient。这就是为什么您可能会观察到差异。
观看此视频以了解有关差异的更多信息:
https://www.youtube.com/watch?v=IOyq-eTRhvo
根据经验,“始终”提取小部件,而不是通过方法创建小部件。
为什么您的 child 小部件没有重建可能是多种原因之一。无论哪种方式,我认为它与本例中的 parents setState() 调用没有任何关系。
child 小部件没有任何理由重建。您似乎正在通过一些全局变量(?)TaskData.tasks...添加内容? child 小部件不会“观察”该变量的变化。所以他们没有重建的理由。
如果您从 parent 注入数据,使用一些状态管理,如 Bloc,或使用 Provider 或 ChangeNotifier 或类似的,用于 PageHeader()、PageBody() 及其 children 建立他们的基础,然后一切都会相应地更新。