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

Flutter首次加载无法获取数据,仅热重载后正常的问题求助

问题解决思路

核心问题是你在异步数据请求未完成时就生成了page,导致首次加载时page拿到的是空数据。下面是具体的修改方案:

1. 修复异步调用的时序问题

getResponse是异步方法,直接在initState里调用后立刻执行page = getPage(),此时请求还没结束,resp还是空值。需要等待请求完成后再更新页面。

修改_LoggedInState类,添加异步初始化方法:

class _LoggedInState extends State<LoggedIn> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  // 初始化page为null,用于判断加载状态
  Widget? page;

  @override
  void initState() {
    super.initState();
    // 调用异步初始化方法
    _loadInitialData();
  }

  // 单独写异步初始化方法,避免直接给initState加async
  Future<void> _loadInitialData() async {
    await getResponse(); // 等待数据请求完成
    setState(() {
      page = getPage(); // 数据就绪后生成页面
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    // 移除这里重复的getResponse调用,避免多次请求数据
  }

  @override
  Widget build(BuildContext context) {
    if (!getToken()) {
      return getLoginScreen();
    }

    return SafeArea(
      child: Scaffold(
        body: page ?? const Center(child: CircularProgressIndicator()),
        // 如果page还没生成,显示加载中
      ),
    );
  }
}

2. 简化getResponse里的重复判断逻辑

原来的嵌套循环可以用contains方法简化,代码更高效易读:

dynamic getResponse() async {
  response = await api.getGlobalResponse();
  resp = GlobalResponse.fromJson(jsonDecode(response));
  
  if (resp?.almacenes != null) {
    for (Almacen alm in resp!.almacenes!) {
      final almacenName = alm.name.toString();
      // 直接判断是否已存在,避免嵌套循环
      if (!options.contains(almacenName)) {
        options.add(almacenName);
      }
    }
  }

  return response;
}

3. 移除无效的setState

你原来写的setState(() {resp = resp;})完全无效,因为没有改变resp的引用或值,根本触发不了UI更新,直接删掉即可。

这样修改后,首次加载时会先显示加载指示器,等数据请求完成后再生成并显示正确的页面,热重载也能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:05:18