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

Flutter Getx Obx无法更新接口返回值 视图残留旧数据问题

问题原因

GetX默认Get.put()采用单例缓存机制,同路由下跳转不会重新创建Controller实例,你把接口请求写在Controller构造函数中,仅会在第一次进入页面时执行一次。后续跳转传入新的pedidoId时,既不会重新执行构造函数拉取新数据,也没有做参数变化的监听逻辑,视图自然一直保留第一次请求返回的旧数据。
另外你在构造函数中执行异步请求不符合GetX的生命周期设计,容易出现依赖未加载完成就执行逻辑的异常。

修复步骤
  • 将pedidoId改为响应式变量,添加值变化监听,id更新时自动触发接口请求
  • 把初始化请求逻辑从构造函数移到GetX官方推荐的onInit生命周期回调中
  • 页面build时校验当前路由参数和Controller存储的id是否一致,不一致时主动更新id触发新请求
  • 移除无意义的numeroFactura.value = ''赋值操作,响应式变量直接赋新值就会触发视图刷新
修复后代码

Controller代码

class TiendaPedidosDetalleController extends GetxController {
  final pedidoId = 0.obs;
  final numeroFactura = '0'.obs;
  final UsersProvider usersProvider = UsersProvider();

  @override
  void onInit() {
    super.onInit();
    // 初始化读取首次传入的订单id
    pedidoId.value = Get.arguments?['pedidoId'] ?? 0;
    // 监听订单id变化,id变更时自动拉取新的详情数据
    ever(pedidoId, (newId) {
      pedidoDetalle(newId);
    });
  }

  /// 对外提供更新订单id的方法
  void updatePedidoId(int newId) {
    pedidoId.value = newId;
  }

  Future<void> pedidoDetalle(int pedidoId) async{
    final ResponseApi responseApi = await usersProvider.pedidoDetalle(pedidoId);
    if (responseApi.success == true) {
      numeroFactura.value = responseApi.data['id'].toString();
    } else {
      Get.snackbar('ERROR', responseApi.message ?? '请求失败');
    }
  }
}

View代码

class TiendaPedidosDetallePage extends StatelessWidget {
  const TiendaPedidosDetallePage({super.key});

  @override
  Widget build(BuildContext context) {
    final TiendaPedidosDetalleController con = Get.put(TiendaPedidosDetalleController());
    // 校验路由传入的新订单id,和当前存储id不一致时更新触发请求
    if (Get.arguments != null) {
      final newPedidoId = Get.arguments['pedidoId'];
      if (newPedidoId != null && newPedidoId != con.pedidoId.value) {
        con.updatePedidoId(newPedidoId);
      }
    }
    return Obx(() => Scaffold(
      appBar: MyAppBar(),
      bottomNavigationBar: MyBottomNavigationBar(),
      body: Column(
        children: [
          Container(
            margin: const EdgeInsets.only(top: 10),
            child: Center(
              child: Text(
                'Tu Ticket # ${con.numeroFactura.value}',
                style: const TextStyle(fontSize: 30),
              ),
            ),
          ),
        ],
      )
    ));
  }
}
额外优化建议
  • 同页面跳转查看不同订单详情时,建议使用Get.off()/Get.offNamed()方式跳转,自动销毁上一个同页面实例,避免页面栈堆积
  • 异步请求方法建议加上Future<void>返回值类型,规范代码类型约束
  • 如果需要每次进入页面都强制刷新数据,可以在onReady生命周期中添加请求逻辑,或者用路由监听回调触发刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:51:25