组件状态
StatelessWidget
StatelessWidget
是无状态的组件。它的内容在生命周期中保持不变,只在创建时构建一次,之后不会重新渲染,除非父组件触发重建。
- 适用场景:
- UI 只依赖外部传入的参数。
- UI 不会动态变化。
StatefulWidget
StatefulWidget
是有状态的组件,它的内容可以根据用户交互或其他事件动态变化。 与 StatelessWidget
不同,它由两部分组成:
- StatefulWidget 类:负责定义组件的不可变部分(构造函数和静态内容)。
- State 类:负责存储和管理组件的可变状态。
Flutter 的设计通过将 StatefulWidget
和 State
分开,清晰地分离了静态结构和动态行为。
为何分成两个类?
- 不可变性:
StatefulWidget
本身是不可变的,只有State
才存储可变数据。这符合 Flutter 对不可变组件的设计理念。 - 重用性:当
StatefulWidget
重建时(例如父组件触发重建),Flutter 不会重新创建对应的State
实例,只是重新关联,这样可以保留组件的状态。
两者区别总结
特性 | StatelessWidget | StatefulWidget |
---|---|---|
是否有状态 | 无状态 | 有状态 |
重新渲染 | 依赖父组件重建 | 状态改变时触发重建 |
组件数据 | 通过构造函数传入 | 通过 State 类存储 |
用途 | 静态内容或短暂 UI | 动态内容,例如交互按钮、表单等 |
实例重用 | 始终创建新实例 | State 可以在 Widget 重建时保留 |
性能开销 | 较低 | 略高(但可通过分离逻辑优化) |
Flutter 将 StatefulWidget
分为两个类是为了实现以下目标:
- 声明式 UI:
Widget
是不可变的,这与声明式 UI 的设计思想一致。 - 状态与界面分离:将不可变部分(
StatefulWidget
)与可变部分(State
)分开,简化逻辑和提升维护性。 - 提高性能:通过保存状态避免不必要的重建开销。
这个分离让开发者的代码更具可读性,同时保证框架的高效运行
dart
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Hello World'),
),
body: const MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> list = [];
@override
Widget build(BuildContext context) {
return ListView(children: [
Column(
children: list.map((value) {
return ListTile(
title: Text('$value'),
);
}).toList(),
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.all(40),
child: ElevatedButton(
onPressed: () {
setState(() {
list.add('Hello World');
});
},
child: const Text('增加')),
)
]);
}
}