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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:02:29