Skip to content

组件状态

StatelessWidget

StatelessWidget 是无状态的组件。它的内容在生命周期中保持不变,只在创建时构建一次,之后不会重新渲染,除非父组件触发重建。

  • 适用场景
    • UI 只依赖外部传入的参数。
    • UI 不会动态变化。

StatefulWidget

StatefulWidget 是有状态的组件,它的内容可以根据用户交互或其他事件动态变化。 与 StatelessWidget 不同,它由两部分组成:

  • StatefulWidget 类:负责定义组件的不可变部分(构造函数和静态内容)。
  • State 类:负责存储和管理组件的可变状态。

Flutter 的设计通过将 StatefulWidgetState 分开,清晰地分离了静态结构和动态行为。

为何分成两个类?

  • 不可变性StatefulWidget 本身是不可变的,只有 State 才存储可变数据。这符合 Flutter 对不可变组件的设计理念。
  • 重用性:当 StatefulWidget 重建时(例如父组件触发重建),Flutter 不会重新创建对应的 State 实例,只是重新关联,这样可以保留组件的状态。

两者区别总结

特性StatelessWidgetStatefulWidget
是否有状态无状态有状态
重新渲染依赖父组件重建状态改变时触发重建
组件数据通过构造函数传入通过 State 类存储
用途静态内容或短暂 UI动态内容,例如交互按钮、表单等
实例重用始终创建新实例State 可以在 Widget 重建时保留
性能开销较低略高(但可通过分离逻辑优化)

Flutter 将 StatefulWidget 分为两个类是为了实现以下目标:

  • 声明式 UIWidget 是不可变的,这与声明式 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('增加')),
      )
    ]);
  }
}