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

Flutter中传递已获取的Snapshot至其他页面并避免重复请求

解决方案

问题根源

  1. 你定义的snapshot getter每次被访问时,都会调用controller.getAllUsers()生成新的Future,导致导航时重复发起请求。
  2. 导航时传递的snapshot要么是未完成的Future,要么是FutureBuilder内部的AsyncSnapshot对象,而非实际的List<RaceModel>数据,所以打印时只会显示实例标识。

步骤1:在State中缓存已获取的数据和请求Future

修改_DashboardState,添加变量存储请求Future和已加载的数据,避免重复请求:

class _DashboardState extends State<Dashboard> {
  final controller = Get.put(RaceController());
  var currentSliderValue = 20.0.obs;
  // 存储请求的Future,避免重复调用getAllUsers
  Future<List<RaceModel>>? _fetchRacesFuture;
  // 缓存已加载完成的数据
  List<RaceModel>? _raceData;

  @override
  void initState() {
    super.initState();
    // 初始化请求Future
    _fetchRacesFuture = controller.getAllUsers(currentSliderValue.value);
  }

  // 滑块值变化时更新请求Future
  void _updateSliderValue(double value) {
    setState(() {
      currentSliderValue.value = value;
      _fetchRacesFuture = controller.getAllUsers(value);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            icon: Icon(Icons.map),
            onPressed: () {
              // 导航时直接传缓存的_raceData
              if (_raceData != null) {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => Racesmap(snap: _raceData!)),
                );
              } else {
                // 数据未加载完成时的提示
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text("数据加载中,请稍后")),
                );
              }
            },
          ),
        ],
      ),
      body: FutureBuilder<List<RaceModel>>(
        future: _fetchRacesFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasData) {
              // 数据加载完成后缓存到_raceData
              _raceData = snapshot.data;
              return ListView.builder(
                itemCount: _raceData!.length,
                itemBuilder: (context, index) {
                  // 你的列表项构建逻辑
                  return ListTile(title: Text(_raceData![index].name));
                },
              );
            } else if (snapshot.hasError) {
              return Center(child: Text("加载失败: ${snapshot.error}"));
            }
          }
          return Center(child: CircularProgressIndicator());
        },
      ),
      // 滑块组件示例
      bottomNavigationBar: Slider(
        value: currentSliderValue.value,
        onChanged: _updateSliderValue,
        min: 0,
        max: 100,
      ),
    );
  }
}

步骤2:修改Racesmap页面的参数类型

确保Racesmap接收的是实际数据类型,而非Future或AsyncSnapshot:

class Racesmap extends StatelessWidget {
  final List<RaceModel> snap;

  const Racesmap({super.key, required this.snap});

  @override
  Widget build(BuildContext context) {
    // 这里可以直接使用snap数据
    print(snap);
    return Scaffold(
      appBar: AppBar(title: Text("Races Map")),
      body: Center(child: Text("共${snap.length}条赛事数据")),
    );
  }
}

关键说明

  • _fetchRacesFuture仅在滑块值变化时更新,避免不必要的重复请求。
  • _raceData缓存已加载完成的数据,导航时直接传递该变量,不会触发新请求。
  • 导航前判断_raceData是否为空,避免数据未加载完成时传递null。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:35:23