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

Flutter中如何解决无限循环问题?附报错与代码分析

如何解决Flutter中Riverpod导致的无限循环(栈溢出)问题?

执行命令 flutter run -d chrome --web-hostname localhost --web-port 7357 时,终端抛出如下报错:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following JSRangeError was thrown building App(dirty, dependencies: [UncontrolledProviderScope],
state: _AppState#e4a9b):
Invalid argument: Maximum call stack size exceeded

The relevant error-causing widget was:
  App App:file:///Users/user/development/projects/flutter/project/lib/src/project.dart:46:21

When the exception was thrown, this was the stack:
packages/riverpod/src/framework/auto_dispose.dart 7:24                     <computed>
packages/riverpod/src/stream_provider/base.dart 110:56                     __
packages/riverpod/src/stream_provider/auto_dispose.dart 42:7               __
packages/riverpod/src/stream_provider/auto_dispose.dart 31:45              createElement
packages/riverpod/src/framework/container.dart 49:32                       [_create]
packages/riverpod/src/framework/container.dart 41:52                       getElement
packages/riverpod/src/framework/container.dart 455:39                      <fn>
packages/riverpod/src/framework/provider_base.dart 75:25                   addListener
packages/riverpod/src/framework/container.dart 298:20                      listen
packages/flutter_riverpod/src/consumer.dart 506:25                         <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 194:23  putIfAbsent
packages/flutter_riverpod/src/consumer.dart 510:8                          watch
packages/project/src/app.dart 61:34                                         build
packages/flutter/src/widgets/framework.dart 4992:27                        build
packages/flutter_riverpod/src/consumer.dart 488:20                         build
packages/flutter/src/widgets/framework.dart 4878:15                        performRebuild
packages/flutter/src/widgets/framework.dart 5050:11                        performRebuild
packages/flutter/src/widgets/framework.dart 4604:5                         rebuild
packages/flutter/src/widgets/framework.dart 4859:5                         [_firstBuild]
packages/flutter/src/widgets/framework.dart 5041:11                        [_firstBuild]
…
════════════════════════════════════════════════════════════════════════════════════════════════════

搜索后确认问题核心是无限循环,但无法定位代码中的循环位置。

项目逻辑:通过Firebase Cloud Firestore设置维护状态(true/false),使用flutter_riverpod包读取该值,若为true则显示维护页面,否则显示默认页面。

相关代码如下:

MaintenanceModel 模型类

class MaintenanceModel {
  MaintenanceModel(
    this.id,
    this.isUnderMaintenance,
  );

  final String id;
  final bool isUnderMaintenance;

  factory MaintenanceModel.fromMap(
    Map<String, dynamic> data,
    String documentId,
  ) {
    final bool? isUnderMaintenance = data["isUnderMaintenance"];

    return MaintenanceModel(
      documentId,
      isUnderMaintenance ?? false,
    );
  }
}

Firestore 文档流工具方法

Stream<T> documentStream<T>({
    required String path,
    required T Function(Map<String, dynamic> data, String documentID) builder,
  }) {
    DocumentReference<Object?> reference = firestore.doc(path);
    Stream<DocumentSnapshot<Object?>> snapshots = reference.snapshots();
    return snapshots.map((snapshot) => builder(
          snapshot.data() == null
              ? {}
              : snapshot.data() as Map<String, dynamic>,
          snapshot.id,
        ));
  }

获取维护状态的流方法

Stream<MaintenanceModel> maintenanceStream() {
  return AppServices.kFirestoreService.documentStream(
    path: "Admins/maintenance",
    builder: (data, documentId) => MaintenanceModel.fromMap(data, documentId),
  );
}

Riverpod StreamProvider

final maintenanceProvider = StreamProvider.autoDispose<MaintenanceModel>((ref) {
  final repository = ref.watch(provider);

  return repository.maintenanceStream();
});

在Widget中使用Provider

final maintenanceValue = ref.watch(maintenanceProvider);

根据状态渲染页面

maintenanceValue.when(
  data: (maintenance) => maintenance.isUnderMaintenance ? MaintenanceScreen() : DefaultScreen(),
  error: (error, stackTrace) => const Center(child: Text("Error!")),
  loading: () => const Center(child: CircularProgressIndicator()),
),

请问如何解决这个无限循环问题?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:50:46