The following message was thrown building Obx(dirty, state: _ObxState#777c8): [Get] the improper use of a GetX has been detected. You should only use GetX or Obx for the specific widget that will be updated. If you are seeing this error, you probably did not insert any observable variables into GetX/Obx or insert them outside the scope that GetX considers suitable for an update (example: GetX => HeavyWidget => variableObservable). If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.
Obx
或GetX
组件错误使用,因为检测到在其中没有使用observable变量
Obx类型
class Obx extends ObxWidget { final WidgetCallback builder; const Obx(this.builder); @override Widget build() => builder(); }
Obx
的定义很简单,它仅接受一个返回Widget
的闭包作为参数
Obx
继承自 ObxWidget
, ObxWidget
里面包含了本次的报错内容
Widget get notifyChilds { final observer = RxInterface.proxy; // 2 RxInterface.proxy = _observer; // 3 final result = widget.build(); // 1 if (!_observer!.canUpdate) { throw """ [Get] the improper use of a GetX has been detected. You should only use GetX or Obx for the specific widget that will be updated. If you are seeing this error, you probably did not insert any observable variables into GetX/Obx or insert them outside the scope that GetX considers suitable for an update (example: GetX => HeavyWidget => variableObservable). If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX. """; } RxInterface.proxy = observer; // 4 return result; }
_observer!.canUpdate
为false
才抛出的错误
查看 _observer
为 RxNotifier
实例
class _ObxState extends State<ObxWidget> { final _observer = RxNotifier(); late StreamSubscription subs; @override void initState() { super.initState(); subs = _observer.listen(_updateTree, cancelOnError: false); } void _updateTree(_) { if (mounted) { setState(() {}); } } @override void dispose() { subs.cancel(); _observer.close(); super.dispose(); } @override Widget build(BuildContext context) => RxInterface.notifyChildren(_observer, widget.build); }
RxNotifier
的实现
class RxNotifier<T> = RxInterface<T> with NotifyManager<T>; mixin NotifyManager<T> { GetStream<T> subject = GetStream<T>(); final _subscriptions = <GetStream, List<StreamSubscription>>{}; bool get canUpdate => _subscriptions.isNotEmpty; /// This is an internal method. /// Subscribe to changes on the inner stream. void addListener(GetStream<T> rxGetx) { if (!_subscriptions.containsKey(rxGetx)) { final subs = rxGetx.listen((data) { if (!subject.isClosed) subject.add(data); }); final listSubscriptions = _subscriptions[rxGetx] ??= <StreamSubscription>[]; listSubscriptions.add(subs); } } StreamSubscription<T> listen( void Function(T) onData, { Function? onError, void Function()? onDone, bool? cancelOnError, }) => subject.listen( onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError ?? false, ); /// Closes the subscriptions for this Rx, releasing the resources. void close() { _subscriptions.forEach((getStream, _subscriptions) { for (final subscription in _subscriptions) { subscription.cancel(); } }); _subscriptions.clear(); subject.close(); } }
canUpdate
时 _subscriptions.isNotEmpty
不能为空
mixin RxObjectMixin<T> on NotifyManager<T> { // ... T get value { if (RxInterface.proxy != null) { RxInterface.proxy!.addListener(subject); } return _value; } // ... }
使用了.value
方法,使用proxy
记录下使用记录,并listen这个变量, 在访问value
时,Obx
尚未创建,也没有对应的RxNotifier
可供记录和监听用