Flutter中传递已获取的Snapshot至其他页面并避免重复请求
解决方案
问题根源
- 你定义的
snapshotgetter每次被访问时,都会调用controller.getAllUsers()生成新的Future,导致导航时重复发起请求。 - 导航时传递的
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
相关产品推荐
相关产品推荐

