通过构造函数传递TeacherModel首次加载显示null问题求助
问题分析与解决方案
核心问题
首次加载时子页面拿到null的原因有两个:
- State类中自行声明的
teacherModel初始值为null,且在异步数据库查询完成前,就提前创建了子页面实例,导致子页面接收的参数为null。 - 热重启后数据库查询可能命中缓存,异步操作快速完成,
teacherModel被及时赋值,因此问题消失。
解决方案(分两种场景)
场景1:直接使用构造函数传入的TeacherModel
如果构造函数已经从其他页面传递了有效的TeacherModel,不需要再从数据库二次获取,直接删除冗余的异步加载逻辑即可:
class TeacherMainScreen extends StatefulWidget { TeacherMainScreen({super.key, required this.teacherModel}); final TeacherModel teacherModel; @override State<TeacherMainScreen> createState() => _TeacherMainScreenState(); } class _TeacherMainScreenState extends State<TeacherMainScreen> { int index = 0; @override Widget build(BuildContext context) { var screen = [ TeacherHomeScreen(model: widget.teacherModel), TeacherSessionScreen(teacherrModel: widget.teacherModel), PersonalAcountScreen(teacherModel: widget.teacherModel), ]; return Scaffold( backgroundColor: Colors.white.withOpacity(0.1), body: screen[index], bottomNavigationBar: NavigationBarTheme( data: NavigationBarThemeData( indicatorColor: AppColors.PRIMARY_COLOR_20, surfaceTintColor: Colors.transparent, labelBehavior: NavigationDestinationLabelBehavior.alwaysShow, labelTextStyle: MaterialStateProperty.all( TextStyle(fontSize: 14, fontFamily: 'Inter'))), child: NavigationBar( backgroundColor: Colors.white, selectedIndex: index, onDestinationSelected: (value) { setState(() { index = value; }); }, destinations: [ NavigationDestination(icon: AppIcon.NEAR_ME, label: 'Explore'), NavigationDestination(icon: AppIcon.CALENDER_MONTH, label: 'Sessions'), NavigationDestination(icon: AppIcon.PERSON, label: 'Account') ], ), ), ); } }
场景2:需要从数据库获取最新数据
如果必须从数据库拉取最新数据,需优化初始化逻辑和页面创建时机:
class TeacherMainScreen extends StatefulWidget { TeacherMainScreen({super.key, required this.teacherModel}); final TeacherModel teacherModel; @override State<TeacherMainScreen> createState() => _TeacherMainScreenState(); } class _TeacherMainScreenState extends State<TeacherMainScreen> { TeacherModel? teacherModel; late bool isLoading; @override void initState() { super.initState(); isLoading = true; // 先用构造函数传入的模型初始化,避免初始为null teacherModel = widget.teacherModel; getData(); } void getData() async { // 从数据库获取最新数据 final latestData = await Database().teacherAllData(); setState(() { teacherModel = latestData; isLoading = false; }); } int index = 0; @override Widget build(BuildContext context) { if (isLoading) { return Scaffold(body: customLoading()); } // 处理模型为空的异常情况 if (teacherModel == null) { return Scaffold(body: Center(child: Text('加载教师数据失败'))); } // 确保模型不为null时再创建子页面 var screen = [ TeacherHomeScreen(model: teacherModel!), TeacherSessionScreen(teacherrModel: teacherModel!), PersonalAcountScreen(teacherModel: teacherModel!), ]; return Scaffold( backgroundColor: Colors.white.withOpacity(0.1), body: screen[index], bottomNavigationBar: NavigationBarTheme( data: NavigationBarThemeData( indicatorColor: AppColors.PRIMARY_COLOR_20, surfaceTintColor: Colors.transparent, labelBehavior: NavigationDestinationLabelBehavior.alwaysShow, labelTextStyle: MaterialStateProperty.all( TextStyle(fontSize: 14, fontFamily: 'Inter'))), child: NavigationBar( backgroundColor: Colors.white, selectedIndex: index, onDestinationSelected: (value) { setState(() { index = value; }); }, destinations: [ NavigationDestination(icon: AppIcon.NEAR_ME, label: 'Explore'), NavigationDestination(icon: AppIcon.CALENDER_MONTH, label: 'Sessions'), NavigationDestination(icon: AppIcon.PERSON, label: 'Account') ], ), ), ); } }
修改要点说明
- 场景2中,先通过
widget.teacherModel初始化State中的teacherModel,避免初始状态为null。 - 将子页面的创建逻辑移到
isLoading结束且teacherModel不为null的分支中,确保子页面接收的参数有效。 - 添加
teacherModel为null的异常处理,避免页面崩溃。
内容的提问来源于stack exchange,提问作者Shafi Munshi
相关产品推荐
相关产品推荐

