从零构建的Bloc事件无法接收数据,请求技术排查
问题描述
首次从零构建Bloc组件,原本设定数值达到特定值时触发错误状态,但测试发现Bloc事件完全接收不到数据。已确认输入框内容变化时会触发DaysChangedEvent事件,但尝试对数据执行int.parse时返回null。
相关代码
Widget代码
class Daytextfield extends StatelessWidget { Daytextfield({ Key? key, required this.digits, required this.hint, }) : super(key: key); final int digits; final String hint; final String texto = ''; @override Widget build(BuildContext context) { final TextEditingController dias = TextEditingController(text: texto); Color color = Colors.black; return BlocConsumer<DaysBloc, DaysState>( listener: (context, state) { if(state is DaysIncorrectState){ color = Colors.red; } else if (state is DaysCorrectState){ color = Colors.green; } }, builder: (context, state) { return TextFormField( onChanged: (value) { BlocProvider.of<DaysBloc>(context).add(DaysChangedEvent(texto: texto)); print(state); // var ree = int.tryParse(texto); print(texto); }, controller: dias, keyboardType: TextInputType.number, textInputAction: TextInputAction.next, textAlign: TextAlign.center, cursorColor: Color.fromARGB(148, 66, 63, 63), style: Theme.of(context) .textTheme .headline1! .copyWith(fontSize: 20, color: color),
Bloc类代码
class DaysBloc extends Bloc<DaysEvent, DaysState> { int max = 360; DaysBloc() : super(DaysInitial()) { on<DaysChangedEvent>((event, emit) { if(event.texto == '123') {emit(DaysIncorrectState(texto: event.texto));} else emit(DaysCorrectState(texto: event.texto)); }); } }
Event类代码
abstract class DaysEvent extends Equatable { const DaysEvent(); @override List<Object> get props => []; } class DaysChangedEvent extends DaysEvent { String texto; DaysChangedEvent({ required this.texto, }); @override List<Object> get props => [texto]; }
State类代码
class DaysInitial extends DaysState {} class DaysCorrectState extends DaysState { String texto; DaysCorrectState({ required this.texto, }); @override List<Object> get props => [texto]; } class DaysIncorrectState extends DaysState { String texto; DaysIncorrectState({ required this.texto, }); @override List<Object> get props => [texto]; }
问题根源与修复
核心问题
- 传递错误的数据:
onChanged回调里传的是类的初始空字符串texto,而非输入框当前的value,导致Bloc始终收到空值,int.tryParse自然返回null。 - 控制器位置错误:
TextEditingController定义在build方法内,每次Widget重建都会重新初始化,无法保留输入内容。 - 颜色更新无效:
color变量在build内定义,listener中修改后不会触发UI重建,State更新时color会被重置为黑色。
修复后的Widget代码
class Daytextfield extends StatelessWidget { Daytextfield({ Key? key, required this.digits, required this.hint, }) : super(key: key); final int digits; final String hint; // 控制器放在类成员位置,避免每次build重建 final TextEditingController dias = TextEditingController(text: ''); @override Widget build(BuildContext context) { return BlocConsumer<DaysBloc, DaysState>( builder: (context, state) { // 直接在builder里根据状态取颜色,确保UI跟随状态更新 Color color = Colors.black; if (state is DaysIncorrectState) { color = Colors.red; } else if (state is DaysCorrectState) { color = Colors.green; } return TextFormField( onChanged: (value) { // 传递输入框当前值value给事件 BlocProvider.of<DaysBloc>(context).add(DaysChangedEvent(texto: value)); print(state); print(value); }, controller: dias, keyboardType: TextInputType.number, textInputAction: TextInputAction.next, textAlign: TextAlign.center, cursorColor: const Color.fromARGB(148, 66, 63, 63), style: Theme.of(context) .textTheme .headline1! .copyWith(fontSize: 20, color: color), ); }, ); } }
额外优化建议
在Bloc里处理字符串转整数的逻辑,更符合职责划分:
on<DaysChangedEvent>((event, emit) { final int? days = int.tryParse(event.texto); // 用数值判断替代字符串判断,逻辑更严谨 if (days == 123) { emit(DaysIncorrectState(texto: event.texto)); } else { emit(DaysCorrectState(texto: event.texto)); } });
内容的提问来源于stack exchange,提问作者Arisbor
相关产品推荐
相关产品推荐

