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

Flutter使用Provider跳转至其他页面时实例数据丢失如何解决?

问题原因
  • 实例不统一:你在initState中调用ListingProvider().getListing()时创建了一个全新的ListingProvider临时实例,和build方法中通过Provider.of(context)获取的、全局注册的共享实例完全独立。你拉取到的4条数据只存在于这个临时实例中,共享实例的onDisplayListing自然为空。
  • 异步时序问题:即便实例统一,getListing是异步网络请求,首次执行build方法时请求还未完成,第一次打印也会返回空列表,只有等到请求完成触发notifyListeners()后,页面重绘时才能拿到数据。
解决方案

1. 修正Provider实例调用方式

不要在initState中新建实例,需要获取全局注册的共享实例来调用拉取方法,注意要加listen: false参数才能在生命周期方法中访问Provider:

@override
initState() {
  super.initState();
  final listingProvider = Provider.of<ListingProvider>(context, listen: false);
  listingProvider.getListing(widget.token);
}

2. 确认顶层已正确注册Provider

请检查你的应用入口代码,确保已经在MaterialApp上层完成了ListingProvider的全局注册:

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => ListingProvider(),
      child: const MyApp(),
    ),
  );
}

3. 适配异步加载逻辑

由于网络请求是异步的,建议增加加载状态和空状态适配,避免首次加载空白:

首先在ListingProvider中新增加载状态

class ListingProvider extends ChangeNotifier {
  var url = Uri.parse('${Constants.apiUrl}listings/');
  bool isLoading = false;
  List<Listing> onDisplayListing = [];

  ListingProvider() {
    print("Listing Provider inicializado");
  }

  getListing(Token token) async {
    isLoading = true;
    notifyListeners();
    try {
      var response = await http.get(
        url,
        headers: {
          'content-type': 'application/json',
          'accept': 'application/json',
          'authorization': "Bearer ${token.token}"
        },
      );
      final nowListingResponse = ListingResponse.fromJson(response.body);
      onDisplayListing = nowListingResponse.results;
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}

然后在页面中根据状态渲染不同内容

@override
Widget build(BuildContext context) {
  final listingProvider = Provider.of<ListingProvider>(context);
  print(listingProvider.onDisplayListing);

  return Scaffold(
    appBar: AppBar(
      title: const Text("Find Shipments"),
    ),
    body: Center(
      child: listingProvider.isLoading 
        ? const CircularProgressIndicator()
        : listingProvider.onDisplayListing.isEmpty
          ? const Text("暂无可用房源数据")
          : ListView.builder(
              itemCount: listingProvider.onDisplayListing.length,
              itemBuilder: (context, index) {
                final item = listingProvider.onDisplayListing[index];
                // 替换为你自定义的Listing项组件
                return ListTile(title: Text(item.name));
              },
            ),
    ),
    drawer: Drawer(
      child: ListView(
        padding: EdgeInsets.zero,
        children: [
          MyHeaderDrawer(
            token: widget.token,
          ),
          myDrawerListOption(),
        ],
      ),
    ),
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:45:04