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

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

在上一篇中,我们已经掌握了:

  • StatefulWidget 与 State 的分工
  • setState 如何触发 UI 更新
  • 状态驱动 UI 的核心思想

但现在,你一定会开始遇到这样的问题:

👉 数据应该在哪里初始化?

👉 请求接口写在哪?

👉 控制器什么时候释放?

这些问题,都和 生命周期(Lifecycle) 有关。


一、什么是生命周期?

生命周期指的是:

一个页面(State)从创建到销毁的全过程

Flutter 中:

  • Widget 会频繁重建
  • State 才是真正"长期存在的对象"

二、State 生命周期概览(先有全局印象)

一个典型的 State 生命周期顺序是:

1️⃣ createState

2️⃣ initState

3️⃣ build

4️⃣ setState(多次)

5️⃣ dispose

📌 你现在不需要死记,后面会反复用。


三、createState:创建 State

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

特点:

  • 只调用一次
  • 负责创建 State 对象
  • 很少写逻辑

四、initState:初始化的最佳位置(非常重要)

复制代码
@override
void initState() {
  super.initState();
  print('initState');
}

initState 的特点:

  • 只调用一次
  • State 创建完成后立即执行
  • 比 build 更早
  • 非常适合做初始化工作

五、initState 能做什么?

✅ 初始化变量

✅ 发起网络请求

✅ 初始化控制器(Animation / TextEditingController)

✅ 订阅事件

📌 原则:

只执行一次的初始化逻辑,放在 initState


六、build:UI 的"说明书"

复制代码
@override
Widget build(BuildContext context) {
  print('build');
  return Text('Hello');
}

build 的特点:

  • 会执行很多次
  • 每次 setState 都会触发
  • 只负责描述 UI

❌ 不要在 build 中:

  • 请求接口
  • 写初始化逻辑

七、setState 在生命周期中的位置

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

setState 并不是生命周期方法,但它会:

👉 触发 build 重新执行

所以生命周期大致是:

复制代码
initState → build → setState → build → setState → build ...

八、dispose:资源释放(非常重要)

复制代码
@override
void dispose() {
  print('dispose');
  super.dispose();
}

dispose 的特点:

  • State 即将被销毁时调用
  • 只调用一次
  • 用于释放资源

九、为什么一定要 dispose?

如果你使用了:

  • Controller
  • Stream
  • Timer
  • 监听器

却没有释放:

👉 内存泄漏 / 异常行为


十、一个完整生命周期示例

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

class _LifeDemoState extends State<LifeDemo> {
  @override
  void initState() {
    super.initState();
    print('initState');
  }

  @override
  Widget build(BuildContext context) {
    print('build');
    return ElevatedButton(
      onPressed: () {
        setState(() {});
      },
      child: Text('刷新'),
    );
  }

  @override
  void dispose() {
    print('dispose');
    super.dispose();
  }
}

运行后你会看到:

  • initState 只一次
  • build 多次
  • dispose 在页面销毁时调用

十一、生命周期的核心职责分工

方法 责任
initState 初始化
build 描述 UI
setState 通知更新
dispose 清理资源

📌 分清职责,是写好 Flutter 的关键。


十二、新手最常见误区

❌ 在 build 中初始化变量

❌ 在 build 中请求接口

❌ 忘记释放控制器

记住:

build 会被反复调用,它不是"开始"的地方


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

你已经能回答:

  • 为什么要在 initState 请求数据
  • 为什么 setState 会刷新 UI
  • 为什么 dispose 一定要写

这意味着:

你开始真正理解 Flutter 的运行机制


十四、总结

本篇你学会了:

  • State 生命周期的基本流程
  • initState / build / dispose 的职责
  • 如何正确放置代码

🔜 下一篇预告

《Flutter 零基础入门(十九):Widget 树、BuildContext 与父子关系》

下一篇我们将学习:

  • Widget 树是如何组织的
  • BuildContext 到底是什么
  • 为什么 context 很重要
  • 父子 Widget 如何通信

理解这一篇后:

你会真正"读懂 Flutter Widget 嵌套结构"

相关推荐
swipe1 分钟前
05|(前端转后全栈)不手写一堆 SQL,后端怎么操作数据库?MyBatis-Plus 入门
前端·后端·全栈
冰暮流星5 分钟前
javascript之date对象
开发语言·javascript·ecmascript
swipe5 分钟前
04|(前端转后全栈)前端状态为什么不够用?从页面数据到 MySQL 持久化
前端·后端·全栈
橘子星6 分钟前
别光看教程!手把手拆解 React Todo 项目,一文吃透 5 个核心概念
前端·javascript
大白要努力!12 分钟前
纯前端实现 PDF 加水印工具 —— 零后端、支持中文、实时预览
前端·pdf·html
石小石Orz14 分钟前
TRAE SOLO实战:实现一个桌面3D助手
前端·人工智能
蜡台20 分钟前
使用 uni-popup 实现数据选择器Data-Picker
前端·javascript·html·uniapp·uni-popup·data-picker
拆房老料21 分钟前
BaseMetas FileView 1.2.0 发布:Office/WPS 大文件预览与内存安全优化实测
前端·产品运营·开源软件
blns_yxl24 分钟前
Promise封装Fetch + 重试机制(HTML+JS)
前端·javascript·html
Elastic 中国社区官方博客29 分钟前
使用重新设计的 AutoOps 更快地进行 Elasticsearch 问题排查
大数据·运维·前端·人工智能·elasticsearch·搜索引擎·全文检索