Flutter:如何实现用户每次导航到页面时重新加载并获取新数据
解决方案
要实现每次导航到BatchScreen(包括返回时)都重新调用API获取最新数据,你可以通过以下步骤修改代码:
1. 将BatchScreen改为ConsumerStatefulWidget
利用Flutter的生命周期方法,在页面首次加载和从其他页面返回时触发数据刷新。
class BatchScreen extends ConsumerStatefulWidget { static const String screenPath = "/BatchScreen"; const BatchScreen({super.key}); @override ConsumerState<BatchScreen> createState() => _BatchScreenState(); } class _BatchScreenState extends ConsumerState<BatchScreen> { @override void initState() { super.initState(); // 页面首次加载时触发数据请求 _refreshBatchData(); } @override void didPopNext() { super.didPopNext(); // 从其他页面返回当前页面时,重新请求数据 _refreshBatchData(); } void _refreshBatchData() { // 获取控制器并调用API请求方法 ref.read(batchControllerProvider.notifier).getBatch(); } @override Widget build(BuildContext context, WidgetRef ref) { final AsyncValue<BatchModel?> batchState = ref.watch(batchControllerProvider); final AuthRepository authRepository = ref.watch(authRepositoryProvider); // 修正监听的类型匹配问题 ref.listen<AsyncValue<BatchModel?>>( batchControllerProvider, (_, state) => state.whenOrNull( error: (error, stackTrace) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(error.toString())), ); }, ), ); Size size = MediaQuery.of(context).size; bool isBegin = false; // 原页面build内容保持不变,此处省略重复代码 return SafeArea( child: Stack( children: [ // 原Scaffold内容 Scaffold(...), // 原batchState.when处理逻辑 batchState.when(...), ], ), ); } }
2. 调整BatchController的初始化逻辑
移除构造函数中自动调用的getBatch(),避免页面初始化时重复请求数据:
class BatchController extends StateNotifier<AsyncValue<BatchModel?>> { final BatchRepository batchRepository; BatchController({required this.batchRepository}) : super(const AsyncValue.data(null)); // 移除构造函数内的getBatch()调用 Future<void> getBatch() async { try { state = const AsyncValue.loading(); await Future.delayed(const Duration(milliseconds: 2000)); final List<BatchModel> batch = await batchRepository.getBatch(); state = AsyncValue.data(batch.first); logDebug('hello'); logDebug(state); } on DioError catch (e) { state = AsyncValue.error( "Uh oh. Something went wrong!", StackTrace.current, ); } } } final batchControllerProvider = StateNotifierProvider<BatchController, AsyncValue<BatchModel?>>( (ref) { final batchRepository = ref.read(batchRepositoryProvider); return BatchController(batchRepository: batchRepository); }, );
原理说明
initState():页面首次创建时触发,执行第一次数据请求。didPopNext():当用户从下级页面返回当前页面时触发,再次执行数据请求,确保获取最新数据。- 通过
ref.read(batchControllerProvider.notifier).getBatch()主动调用API请求方法,替代原构造函数中的自动调用,避免重复请求。
内容的提问来源于stack exchange,提问作者DarkSide77
相关产品推荐
相关产品推荐

