Flutter使用popUntil传值至前页面时遇Cannot modify unmodifiable map错误
Flutter popUntil传递数据时触发"无法修改不可变映射"错误解决
错误信息
未处理的异常:不支持的操作:无法修改不可变映射
原错误日志:[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: Unsupported operation: Cannot modify unmodifiable map
操作流程
1) 路由配置
Route<dynamic> generateRoute(RouteSettings settings) { switch (settings.name) { case LoginViewRoute: String navigatedScreen = settings.arguments as String; return MaterialPageRoute( settings: RouteSettings(name: LoginViewRoute, arguments: Map()), builder: (context) => LoginPage( navigatedPage: navigatedScreen, )); } }
2) 页面跳转(从Home页跳转到Login页)
Navigator.pushNamed(context, LoginViewRoute, arguments: HomeViewRoute).then((value) { final arguments = ModalRoute.of(context)?.settings.arguments as Map; bool result = arguments[IS_LOGIN_COMPLTED]; if (result) { _bloc.onLoggedIn(); print(User().email); } });
3) 返回数据处理(Login页中执行)
Navigator.of(context).popUntil((route) { if (route.settings.name == widget.navigatedPage) { (route.settings.arguments as Map)[IS_LOGIN_COMPLTED] = true; return true; } else { return false; }
错误触发点:
(route.settings.arguments as Map)[IS_LOGIN_COMPLTED] = true;
错误原因
Flutter的RouteSettings.arguments默认会被包装为不可变映射(UnmodifiableMapView),即使初始传入的是可变Map,Flutter内部也可能将其转为不可变实例,直接修改会触发上述异常。此外,RouteSettings设计初衷是传递路由初始化参数,并非页面间返回数据的载体。
解决方案
方案1:使用Navigator.pop返回数据(推荐)
这是Flutter页面间传递返回数据的标准方式,无需修改路由参数:
修改跳转页的回调逻辑(Home页)
Navigator.pushNamed(context, LoginViewRoute, arguments: HomeViewRoute).then((loginResult) { // 直接接收pop返回的数据 if (loginResult == true) { _bloc.onLoggedIn(); print(User().email); } });
修改Login页的返回逻辑
Navigator.of(context).popUntil((route) { if (route.settings.name == widget.navigatedPage) { // 向目标页面返回数据 Navigator.of(context).pop(true); return true; } else { return false; } });
若只需返回上一级页面,无需跳过中间路由,可简化为:
Navigator.pop(context, true);
方案2:确保目标路由的arguments为可变Map(不推荐)
若坚持通过修改RouteSettings.arguments传递数据,需保证目标路由(如Home页)在创建时传入可变空Map:
// 修改HomeViewRoute的路由配置 case HomeViewRoute: return MaterialPageRoute( settings: RouteSettings(name: HomeViewRoute, arguments: {}), // 传入可变Map builder: (context) => HomePage(), );
这种方式不符合Flutter路由设计规范,易引发后续维护问题,谨慎使用。
内容的提问来源于stack exchange,提问作者kokoko
相关产品推荐
相关产品推荐

