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
相关产品推荐
相关产品推荐

