StatelessWidget 与 StatefulWidget:状态到底放哪里

区分无状态组件和有状态组件,理解 setState 的使用边界。

状态Widget

无状态与有状态

StatelessWidget 适合只依赖外部传入参数的组件,例如标题、按钮、展示卡片。StatefulWidget 适合组件内部有变化的数据,例如计数器、输入框状态、Tab 选中项、局部展开折叠。

setState 的本质

setState 并不是直接修改界面,而是告诉 Flutter:这个 State 的数据变了,请重新执行 build。它适合局部、简单、生命周期短的状态。

class CounterBox extends StatefulWidget {
  const CounterBox({super.key});

  @override
  State<CounterBox> createState() => _CounterBoxState();
}

class _CounterBoxState extends State<CounterBox> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('点击次数:$count'),
        ElevatedButton(
          onPressed: () => setState(() => count++),
          child: const Text('增加'),
        ),
      ],
    );
  }
}

实战建议

  • 页面内部临时状态用 setState,不要一上来就引入复杂状态库。
  • 跨页面共享状态再考虑 Provider、Riverpod、Bloc 等方案。
  • 不要在 setState 中执行耗时操作,只放状态修改。
  • dispose 中释放 controller、focusNode、stream subscription。

官方参考