Flutter无状态组件结合Provider使用时,TextEditingController的销毁位置与时机问询
Flutter无状态组件结合Provider使用时,TextEditingController的销毁位置与时机问询
嘿,这个问题问得很实在!咱们来好好捋捋~
首先你得知道,你现在是在无状态组件里写的逻辑,无状态组件本身没有dispose生命周期方法,所以没法像有状态组件那样在类的dispose()里销毁控制器。那咱们得找个控制器彻底不再被使用的时机来处理它。
看你代码里的_textController,它是在onPressed的异步方法里创建的,而且全程只服务于弹出的那个对话框。当showDialog的异步操作完成后——不管用户是点了取消、确认,还是用物理返回键关掉了对话框——这个控制器就完全失去作用了,这时候就是销毁它的最佳时机。
具体改法超简单,就在await showDialog(...)之后,直接调用_textController.dispose()就行,不管result是不是null都要调用,修改后的代码片段大概是这样:
TextButton( onPressed: () async { final _textController = TextEditingController(); final result = await showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('....'), content: TextField( controller: _textController, ), actions: [ TextButton( child: const Text('Cancel'), onPressed: () { Navigator.pop(context); }, ), TextButton( child: const Text('Add'), onPressed: () { Navigator.pop(context, _textController.text); }, ), ], ); }, ); // 对话框关闭后,立刻销毁控制器,不管操作结果如何 _textController.dispose(); if (result != null) { context.read<PatientProvider>().updatePatientName(result as String); } }, child: Text(context.watch<PatientProvider>().patient.name), )
为啥这么做最稳妥?因为不管对话框以什么方式关闭,await showDialog都会执行完毕,这时候控制器已经没有任何关联的Widget了,调用dispose不会有任何问题,还能避免内存泄漏。要是你想着在Cancel或者Add的回调里分别调用dispose,不仅会写重复代码,还会漏掉用户用物理返回键关闭对话框的情况,那样控制器就没法被销毁,会造成不必要的内存占用。
内容来源于stack exchange
相关产品推荐
相关产品推荐

