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

相关推荐
上海懒图科技14 分钟前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥36 分钟前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易1 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
码途行者1 小时前
网站的SQL 注入:从攻击原理到防御措施
开发语言·sql·php
旖旎夜光2 小时前
【C++ 基础入门】C++ 多态(中):虚函数表、多态原理与动静绑定
开发语言·c++·笔记·学习
恋猫de小郭2 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter
你看我名字2 小时前
产品参数昨天还对,今天已过期:数眼智能与大模型应用如何做资料版本校验
开发语言·架构
严肃小白兔2 小时前
TanStack Router 更新构建工具链:Node.js 兼容性、路由分割与前端工程实践
前端·node.js·状态模式
IT_陈寒3 小时前
Vue这个奇葩的响应式问题让我加班到凌晨
前端·人工智能·后端
老秦包你会3 小时前
计算机网络第二课 ----Socket(套接字)编程预备
开发语言·计算机网络·php