Flutter使用addTaskCallback跨组件传值返回null的问题排查
回调传值为null的核心原因
- 你在
AddTaskScreen的build方法内部声明了局部变量String newTaskTitle,这个变量的生命周期完全依附于每一次build方法的执行流程。只要组件触发任意重建,这个变量就会被重新初始化为null,此前你通过TextField的onChanged回调给它赋值的输入内容会直接被丢弃。 - 你使用的
AddTaskScreen是无状态组件(StatelessWidget),本身不具备持有可变状态的能力:TextField输入时修改的只是当前build帧的临时局部变量,和FlatButton点击时读取的变量没有绑定为同一个持久化实例,最终传参时自然会读到未初始化的null值。
可行修复方案
- 将
AddTaskScreen改造为有状态组件(StatefulWidget),把newTaskTitle移到State类的成员变量位置,不再放在build方法内部。变量的生命周期会和State对象绑定,不会因为组件重建被重置,输入值可以被正常持久保存。 - 更可靠的实现方式是给TextField绑定
TextEditingController,直接通过controller的text属性获取输入内容,不依赖临时局部变量存值,从根源上规避局部变量被重置的问题。
改造后的核心代码参考
class AddTaskScreen extends StatefulWidget { // 给回调明确参数类型,避免无类型声明带来的传参错误 final void Function(String? taskTitle) addTaskCallback; AddTaskScreen(this.addTaskCallback); @override State<AddTaskScreen> createState() => _AddTaskScreenState(); } class _AddTaskScreenState extends State<AddTaskScreen> { // 持久化存储输入内容,不再是build方法内的临时局部变量 String? newTaskTitle; @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(20.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextField( autofocus: true, textAlign: TextAlign.center, onChanged: (inputText) { newTaskTitle = inputText; }, ), SizedBox(height: 10.0), FlatButton( color: Colors.lightBlueAccent, onPressed: () { // 触发回调传值 widget.addTaskCallback(newTaskTitle); // 传值完成后手动关闭底部弹窗,避免残留 Navigator.pop(context); }, child: Text( 'Add', style: TextStyle(color: Colors.white), ), ) ], ), ); } }
补充提示:
- 完成传值后不要忘记调用
Navigator.pop(context)关闭底部弹窗,否则回调执行完成后弹窗仍会停留在界面上,后续操作容易出现状态异常。- 父组件侧接收到传值后,需要调用
setState更新任务列表,才能在UI上展示新增的任务内容。
内容的提问来源于stack exchange,提问作者Mohamed Nabil
相关产品推荐
相关产品推荐

