Flutter异步加载Map传值时出现MaterialApp内jsonResult为null的问题
核心问题
你碰到的jsonResult取值为null,本质是异步执行时机和Flutter组件构建周期不匹配导致的:
- 在
initState中调用的loadJson是异步方法,调用后不会阻塞后续执行流程。组件初始化的固定顺序是:触发initState→ 立刻执行build方法渲染UI → 此时后台的文件IO、JSON解析操作还在执行,jsonResult依然是声明时的初始值null - 就算后续
loadJson执行完成给jsonResult赋了正确的Map值,由于没有主动触发组件重建,MaterialApp里读取的还是第一次build时缓存的null快照,不会自动同步最新的变量值。
修复方向
- 用
setState包裹jsonResult的最终赋值逻辑,等异步加载完成后主动通知Flutter重新执行build流程,获取最新的变量值 - 加加载态兜底:变量未完成初始化时,先渲染加载占位组件,避免把null值直接传给下级页面
- 修正
initState的执行顺序:先调用super.initState(),再执行其他初始化逻辑
可参考的改造代码
JjModel jmodel = JjModel(); dynamic jsonResult; bool isLoading = true; loadJson() async { Map<String, dynamic> mapInicial = jmodel.informacoesIniciais(); final Directory _appDocDir = await getApplicationDocumentsDirectory(); final Directory _appDocDirFolder = Directory('${_appDocDir.path}/fileSettings'); File jsonFile = File('${_appDocDirFolder.path}/Preferences.json'); if (await jsonFile.exists()) { String data = jsonFile.readAsStringSync(); jsonResult = json.decode(data); } else { final Directory _appDocDirNewFolder = await _appDocDirFolder.create(recursive: true); File jsonFile = File('${_appDocDirNewFolder.path}/Preferences.json'); jsonResult = mapInicial; } // 赋值完成后触发组件重建 setState(() { isLoading = false; }); return jsonResult; } @override void initState() { super.initState(); loadJson(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Menu de Serviços', debugShowCheckedModeBanner: false, theme: androidTheme(), // 加载完成后才渲染目标页面,未完成时显示加载态 home: isLoading ? const Scaffold(body: Center(child: CircularProgressIndicator())) : ServiceList(jsonResult: jsonResult), ); }
补充说明:如果不适合在当前页面加加载占位,也可以把路由跳转逻辑挪到
loadJson执行完成的回调里,等拿到完整Map值再通过路由参数传给目标页面,从根源上避免异步流程下传值为空的问题。
内容的提问来源于stack exchange,提问作者Patric Guisolffi
相关产品推荐
相关产品推荐

