You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么StatefulWidget传入新构造数据时不会重新构建对应的State对象?

问题核心原因

Flutter框架对StatefulWidget的State实例复用规则是:当新构建的Widget和之前同位置的Widget的runtimeType、key两个属性完全相同时,会复用已有的State实例,不会重新执行createState()方法,initState()生命周期自然也只会在State第一次创建时触发一次。
你两次构建TrainsPage时没有指定自定义key,所以框架复用了第一次创建的_TrainsPageState实例,只更新了State实例持有的widget属性,但是你把routes存在了State的本地变量_routes里,又没有监听widget.routes的变化,所以数据一直停留在第一次传入的空列表状态。

解决方法(三选一即可)

方案1:给TrainsPage指定唯一标识的Key

当Key发生变化时,框架会直接销毁旧的State实例,创建新的State实例,initState()会正常触发读取新的routes:

Widget pageSelector() {
   if (_selectedIndex == 2) {
      // 用能标识routes变化的属性作为ValueKey,比如routes的hashCode
      return TrainsPage(key: ValueKey(_routes.hashCode), routes: _routes);
    } else
      return const Text("");
  }

方案2:在State中重写didUpdateWidget生命周期监听属性变化

该生命周期会在State持有的widget属性更新时触发,在此处同步本地的_routes即可:

class _TrainsPageState extends State<TrainsPage> {
  List<RSRoute> _routes = List.empty();

  @override
  void initState() {
    super.initState();
    _routes = List<RSRoute>.from(widget.routes);
  }

  // 新增这段代码
  @override
  void didUpdateWidget(covariant TrainsPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.routes != widget.routes) {
      setState(() {
        _routes = List<RSRoute>.from(widget.routes);
      });
    }
  }
}

方案3:直接使用widget.routes,无需本地存副本

如果TrainsPage内部不需要修改routes列表,完全可以直接使用widget.routes做展示,不需要在State里单独存一份_routes,也就不会有数据同步的问题。


内容的提问来源于stack exchange,提问作者Alexander Roehnisch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:36:04