Flutter中返回bool类型的FutureBuilder不工作,报Null非bool子类型错误
问题原因&修复方案
- 错误1:
FutureBuilder的builder回调中不允许调用setState。build阶段触发状态更新会导致无限重绘,严重影响性能且逻辑异常。 - 错误2:
getShipValue方法未做空安全校验。Firestore返回的文档可能不存在、data()可能为空、ShippedInd字段可能缺失或不是bool类型,直接强制取值会触发空类型报错。 - 错误3:取值逻辑错误。你在
snapshot.hasData为true时直接固定把isSwitch设为true,完全没有使用Firestore返回的实际值,且未处理加载中、请求失败的边界状态,Switch在请求完成前拿到的也是isSwitch的初始空值。 - 优化点:不要直接在
FutureBuilder的future参数里直接调用getShipValue(),否则每次组件重build都会重新发起Firestore请求,建议在initState中提前请求并保存Future实例,赋值给变量再传给FutureBuilder。
修复后代码
取值方法调整
Future<bool> getShipValue() async { try { var doc = await FirebaseFirestore.instance .collection('OrderDetails') .doc(order.orderId) .get(); if (doc.exists) { var data = doc.data(); // 校验字段存在且为bool类型,不存在/类型不对默认返回false(可根据需求调整默认值) return data?['ShippedInd'] ?? false; } // 文档不存在返回默认值 return false; } catch (e) { // 请求异常返回默认值 return false; } }
FutureBuilder调整
不需要再依赖外部的isSwitch变量做初始值,直接读取Future返回结果即可,如果需要保留本地开关操作的状态,可在handleSwitch方法中更新isSwitch的值:
FutureBuilder<bool>( future: getShipValue(), builder: (context, snapshot) { // 加载中状态可按需替换为加载指示器 if (snapshot.connectionState == ConnectionState.waiting) { return CupertinoSwitch( value: false, onChanged: null, ); } // 读取返回值,为空时用默认值兜底 bool currentValue = snapshot.data ?? false; return CupertinoSwitch( value: currentValue, onChanged: (val) { handleSwitch(val); }, ); } )
内容的提问来源于stack exchange,提问作者Aftab
相关产品推荐
相关产品推荐

