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 页面"从出生到销毁"的全过程

相关推荐
星恒随风几秒前
从0开始的操作系统(3)
开发语言·笔记·学习
开发者联盟league1 分钟前
pip install出现报错ERROR: Cannot set --home and --prefix together
开发语言·python·pip
杖雍皓5 分钟前
Markstream-VUE:构建高性能流式 Markdown 渲染器
前端·javascript·vue.js·markdown·流式输出
FlagOS智算系统软件栈5 分钟前
众智FlagOS完成腾讯混元MT2多语翻译模型全系列多芯片适配:英伟达/华为/平头哥三芯开箱即用
开发语言·人工智能·开源
東隅已逝,桑榆非晚6 分钟前
C语言内存函数
c语言·开发语言·笔记·算法
lly2024068 分钟前
Docker 安装 MySQL
开发语言
techdashen11 分钟前
在 Async Rust 中实现请求合并(Request Coalescing)
开发语言·后端·rust
ZC跨境爬虫13 分钟前
模块化烹饪小程序开发日记 Day6:(菜谱列表接口开发与日志调试实践)
前端·javascript·css·ui·微信小程序·html
RSTJ_162516 分钟前
PYTHON+AI LLM DAY FIFITY-THREE
开发语言·人工智能·python
JAVA社区17 分钟前
Java进阶全套教程(一)—— 数据框架Mybatis详解
java·开发语言·面试·职场和发展·mybatis