17.Flutter 零基础入门(十七):StatelessWidget 与 State 的第一次分离

Flutter 零基础入门(十七):StatelessWidget 与 State 的第一次分离

在上一篇中,我们已经正式进入 Flutter,并完成了:

  • 第一个 Flutter 页面
  • Widget 树的理解
  • StatelessWidget 与 build 方法

但你一定会产生一个疑问:

👉 如果页面内容要变化怎么办?

👉 按钮点击后,文字如何改变?

这一篇,我们来解决 Flutter 中最核心的问题

👉 状态(State)从哪里来?


一、StatelessWidget 的边界

先回顾 StatelessWidget:

dart 复制代码
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello');
  }
}

特点非常明确:

  • 没有状态
  • 内容固定
  • 一旦创建,不会变化

📌 所以:

StatelessWidget 天生不适合"会变的 UI"


二、什么是 State(状态)?

在 Flutter 中,状态指的是:

影响 UI 显示的数据

例如:

  • 计数器的数字
  • 是否登录
  • 是否加载中
  • 当前选中项

📌 一句话理解:

状态变了,UI 就该变


三、一个"错误但常见"的新手尝试

复制代码
class Counter extends StatelessWidget {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Text('$count');
  }
}

你可能会想:

count 不就行了吗?

❌ 这是行不通的。

原因是:

  • StatelessWidget 不会监听变量变化
  • Flutter 不会重新 build

四、StatefulWidget 的出现

为了解决"UI 需要变化"的问题,Flutter 引入了:

👉 StatefulWidget

它的核心思想是:

Widget 负责描述 UI
State 负责保存和管理状态


五、StatefulWidget 的基本结构

复制代码
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() {
    return _CounterState();
  }
}

对应的 State:

复制代码
class _CounterState extends State<Counter> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Text('$count');
  }
}

📌 注意:

  • Widget 和 State 是两个类
  • State 才是真正"活着的部分"

六、为什么要拆成两个类?

这是 Flutter 的设计核心

  • Widget:不可变(immutable)
  • State:可变(mutable)

好处:

  • UI 描述稳定
  • 状态变化可控
  • Flutter 可以高效更新界面

七、setState:状态变化的"开关"

仅仅修改变量是不够的

复制代码
count++;

你必须告诉 Flutter:

状态变了,需要重新 build

这就是 setState 的作用。


八、setState 的正确用法

复制代码
setState(() {
  count++;
});

含义是:

  • 在回调中修改状态
  • Flutter 重新调用 build

📌 本质:

setState = 通知 Flutter 刷新 UI


九、一个完整的计数器示例

复制代码
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('当前计数:$count'),
        ElevatedButton(
          onPressed: () {
            setState(() {
              count++;
            });
          },
          child: Text('加 1'),
        ),
      ],
    );
  }
}

十、State 是如何驱动 UI 的?

流程非常重要:

1️⃣ 用户点击按钮

2️⃣ 调用 setState

3️⃣ Flutter 标记当前 State 为"脏"

4️⃣ build 重新执行

5️⃣ UI 更新

📌 你不需要手动操作 UI。


十一、Widget、State、build 的关系图

复制代码
StatefulWidget(不可变)
        ↓
     State(可变)
        ↓
     build()
        ↓
       UI

这张图,你以后会反复用到。


十二、新手最容易犯的错误

❌ 在 build 中写逻辑

❌ 忘记使用 setState

❌ 把状态写在 StatelessWidget 中

记住一句话:

状态只存在于 State 中


十三、这一篇你真正理解了什么?

你已经理解了 Flutter 的核心哲学:

UI 是状态的映射结果

这也是 Flutter、React、Vue 的共同思想。


十四、总结

本篇你学会了:

  • StatelessWidget 的边界
  • 什么是 State
  • StatefulWidget 的结构
  • setState 的作用

你已经正式跨入:

Flutter 状态驱动 UI 的世界


🔜 下一篇预告

《Flutter 零基础入门(十八):StatefulWidget 生命周期初识》

下一篇我们将学习:

  • initState 是什么时候执行的?
  • dispose 是干什么的?
  • State 的生命周期顺序
  • 为什么要释放资源?

从下一篇开始:

你将真正理解 Flutter 页面"从出生到销毁"的全过程

相关推荐
烤麻辣烫1 小时前
java进阶--刷题与详解-1
java·开发语言·学习·intellij-idea
编程大师哥1 小时前
C++ 中解锁 Redis
开发语言·c++·redis
我是小鳄鱼1 小时前
Day 3: Bash 工具-- 30天复刻了一个 Claude Code
开发语言·bash
小小仙。1 小时前
IT自学第十八天
java·开发语言·算法
柒儿吖1 小时前
Flutter跨平台三方库image_picker在鸿蒙中的使用指南
flutter·华为·harmonyos
世人万千丶1 小时前
鸿蒙跨端框架Flutter学习day 2、常用UI组件-折行布局 Wrap & Chip
学习·flutter·ui·华为·harmonyos·鸿蒙
桃子叔叔1 小时前
react-wavesurfer录音组件2:前端如何处理后端返回的仅Blob字段
前端·react.js·状态模式
nie_xl1 小时前
VS/TRAE中设置本地maven地址的方法
运维·服务器·前端
散峰而望2 小时前
【算法竞赛】队列和 queue
开发语言·数据结构·c++·算法·链表·github·线性回归