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
相关产品推荐
相关产品推荐

