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

使用GetX状态管理时热重启无法渲染数据的问题求助

问题根源与修复方案

核心问题

你的代码存在两个关键问题导致Hot Restart后UI不更新:

  1. 状态更新未触发响应式监听:虽然userModelList初始声明为RxList,但后续直接用userModelList = (await controller.getApi())!;替换了整个列表对象,导致Obx监听的原RxList引用失效,数据变化无法通知UI刷新。
  2. 无效的异步调用方式:Widget的build方法中controller.getUserModels().reactive完全是错误用法,既无法触发响应式,还会在每次build时重复发起请求。

修复步骤

1. 修正控制器(UserModelController)

class UserModelController extends GetxController {
  // 正确声明RxList,无需加?,默认空列表
  final userModelList = <UserModel?>[].obs;
  // ApiService是普通服务,无需Get.put,直接实例化
  final ApiService apiService = ApiService();

  @override
  void onInit() {
    super.onInit();
    // 初始化时自动请求数据,避免在build中重复调用
    getUserModels();
  }

  Future<void> getUserModels() async {
    try {
      final users = await apiService.getApi();
      // 使用assignAll更新RxList,保持原引用不变,触发Obx监听
      userModelList.assignAll(users ?? []);
      print('userModelList length: ${userModelList.length}');
    } catch (error) {
      print('error UserModelController: $error');
    }
  }
}

2. 修正Widget(ObxListView)

void main() {
  // 提前注册控制器,确保全局唯一实例
  Get.put(UserModelController());
  runApp(const GetMaterialApp(home: ObxListView()));
}

class ObxListView extends StatelessWidget {
  const ObxListView({Key? key}) : super(key: key);

  // 通过Get.find获取已注册的控制器实例
  final UserModelController controller = Get.find<UserModelController>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GetX List'),
        centerTitle: true,
      ),
      body: Center(
        child: Column(
          children: [
            Obx(() => Flexible(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: ListView.builder(
                      // RxList的length不会为null,直接使用
                      itemCount: controller.userModelList.length,
                      itemBuilder: (context, index) {
                        final user = controller.userModelList[index];
                        if (user == null) return const SizedBox.shrink();
                        return Card(
                          shape: const OutlineInputBorder(
                              borderRadius: BorderRadius.all(Radius.circular(10))),
                          margin: const EdgeInsets.all(2),
                          child: ListTile(
                            title: Row(
                              children: [
                                Text('Name: ${user.first_name}'),
                                const SizedBox(width: 10),
                                Text(user.last_name),
                              ],
                            ),
                            subtitle: Text(user.email),
                            leading: CircleAvatar(
                              backgroundImage: NetworkImage(user.avatar),
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                )),
            ElevatedButton(
                onPressed: () {
                  print('length: ${controller.userModelList.length}');
                  print('name ${controller.userModelList[0]?.first_name}');
                  print('name ${controller.userModelList[1]?.first_name}');
                },
                child: const Text('Test Button')),
          ],
        ),
      ),
    );
  }
}

为什么Hot Reload能临时生效?

Hot Reload只会重载代码逻辑,不会重建整个应用的依赖树,控制器的RxList引用保持不变。而Hot Restart会完全重启应用,重新创建控制器实例,此时错误的赋值方式会彻底切断Obx的监听链路,导致UI无法感知数据变化。

内容的提问来源于stack exchange,提问作者Dragatus of Roda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 12:05:44