Flutter StatelessWidget 和 StatefulWidget 区别 + 场景用法

8 阅读4分钟

一、核心区别

  • StatelessWidget(无状态组件)页面数据不会变,渲染一次就不动了,没有可变状态
  • StatefulWidget(有状态组件)页面数据会变(点击按钮、输入文字、记计器等),拥有可变状态,能刷新 UI

二、详细对比

表格

特性StatelessWidgetStatefulWidget
是否有状态❌ 无✅ 有(存放在 State 里)
能否刷新 UI❌ 不能(数据写死后无法修改)✅ 能(调用 setState() 刷新)
生命周期简单(仅构建)复杂(创建→更新→销毁)
性能更高(无刷新开销)稍低(有状态管理)
结构一个类,直接实现 build两个类:Widget + State
使用难度简单稍复杂

三、怎么选择用哪个?

用 StatelessWidget 的场景(静态展示)

只要页面内容不会主动变化,一律用它!(性能最好)

  • 纯文本、图标、静态图片
  • 标题栏、分割线、静态卡片
  • 不需要交互、不需要修改数据的 UI
  • 列表里的静态 item

例子:登录页标题、APP 图标、固定文案、静态底部导航。


用 StatefulWidget 的场景(动态交互)

只要页面会变、会交互,必须用它!

  • 点击按钮改变文字 / 颜色 / 显示隐藏
  • 输入框、表单、勾选框、开关
  • 倒计时、轮播图、下拉刷新
  • 网络请求后更新页面
  • 视频 / 音乐播放界面

例子:计时器、登录页输入框、列表刷新、设置页开关。


四、性能区分原理


4-1、核心结论

StatelessWidget ≈ 一次性渲染,几乎无额外开销

StatefulWidget ≈ 带状态管理 + 可触发重建,有额外开销

性能差距的本质来自以下几点:

  1. 结构复杂度
  2. 重建(rebuild)机制
  3. setState () 带来的连锁刷新

4-2、底层原理:两者的结构区别

1. StatelessWidget 结构

StatelessWidget
  ↓
build()  【只执行一次,除非父组件刷新】
  • 没有状态对象
  • 没有 State 类
  • 没有生命周期监听
  • 内存占用更小

2. StatefulWidget 结构

StatefulWidget  ← 本身不可变
  ↓
创建 State 对象  ← 【多出来的一层】
  ↓
State 持有状态、生命周期、setState

多出来的东西:

  • State 实例(内存)
  • 生命周期钩子(initState、dispose、didUpdateWidget...)
  • 状态监听与刷新机制
  • 框架需要跟踪管理它

这是第一层性能开销:结构更重。


4-3、最关键:重建(Rebuild)机制不同

✅ Stateless 的重建规则

  • 自己不能主动刷新自己
  • 只有父组件刷新时,它才会跟着重建
  • 重建成本极低:只是重新执行 build ()

❌ Stateful 的重建规则

  • 自己可以主动刷新自己setState()
  • 一旦调用 setState整个子树都会重建
  • 即使数据没变,也会触发重建

举个例子:

setState(() {
  _count++;
});

这行代码会让:

  1. 当前 State 标记为dirty
  2. 整个 build () 方法重新执行
  3. 页面里所有子组件全部重新构建

这是Stateful 性能不如 Stateless 的核心原因


4-4、内存与垃圾回收原理

Stateless

  • 组件是 immutable(不可变)
  • 无额外对象,无监听
  • 销毁时直接回收,无残留

Stateful

  • Widget + State 两个对象
  • State 会持有上下文、状态、订阅
  • 销毁时需要解绑、释放、回收
  • 更容易产生内存滞留

4-5、最直白的性能对比

表格

行为StatelessWidgetStatefulWidget
自身能否刷新❌ 不能✅ 能(setState)
重建频率
内存占用
框架监听
生命周期完整
重建消耗极低高(子树全部重绘)

五、为什么官方强烈推荐:能用 Stateless 就不用 Stateful?

因为:

1. Stateful 会带来不必要的重建

你只想改一个数字 → 结果整个页面都重建了。

2. Stateful 更容易写出性能差的代码

新手最容易犯的错:

  • 整个页面用一个巨大 Stateful
  • 随便点个按钮就调用 setState
  • 页面一复杂就卡顿

3. Stateless 更简单、更稳定、框架优化更好


六、总结底层原理

Stateless 性能高的原因:

无状态、无管理、不可变、不主动刷新、重建成本极低。

Stateful 性能相对低的原因

带状态、带生命周期、可主动调用 setState 重建整个子树,内存与调度开销更大。

页面内容永远不变 → Stateless(最快)
页面内容会变/会交互 → Stateful(必须用)

最终总结

  1. Stateless:轻量、无状态、不主动刷新 → 性能最高
  2. Stateful:重量、带状态、可 setState 刷新 → 性能稍低
  3. 差距来源:重建机制 + 结构复杂度 + 状态管理开销
  4. 最佳实践:组件最小化 + 能无状态则无状态