为什么要为订阅和 ChangeNotifiers 实现 UpdateWidget?



我创建了一个自定义小部件,该小部件侦听ChangeNotifier并在通知程序触发时调用提供的回调。这用于在通知程序更改时执行一次性任务,例如导航。

一切似乎都很好,但偶然地,我偶然发现了didUpdateWidget的文档,其中指出:

如果 State 的构建方法依赖于本身可以更改状态的对象,例如 ChangeNotifier 或 Stream,或者可以订阅以接收通知的其他对象,请确保在 initState、didUpdateWidget 中正确订阅和取消订阅,并释放:

  • 在 initState 中,订阅对象。
  • 在 didUpdateWidget 中,如果更新的小部件配置需要替换对象,请取消订阅旧对象并订阅新对象。
  • 在释放中,取消订阅对象。

出于显而易见的原因,我正在处理第一点和最后一点,但是有人可以阐明为什么我也必须实现didUpdateWidget吗?如果我不这样做,会出什么问题?

奖励问题:我还没有在我的应用程序中使用提供程序。它是否已经开箱即用地提供了这样的东西?我找不到这样的东西。

我的小部件代码:

class ChangeNotifierListener<T extends ChangeNotifier> extends StatefulWidget {
final Widget child;
final T changeNotifier;
final void Function(T changeNotifier) onChanged;
ChangeNotifierListener(
{@required this.child,
@required this.changeNotifier,
@required this.onChanged});
@override
_ChangeNotifierListenerState createState() =>
_ChangeNotifierListenerState<T>();
}
class _ChangeNotifierListenerState<T extends ChangeNotifier>
extends State<ChangeNotifierListener<T>> {
VoidCallback _callback;
@override
Widget build(BuildContext context) => widget.child;
@override
void initState() {
super.initState();
_callback = () {
widget.onChanged(widget.changeNotifier);
};
widget.changeNotifier.addListener(_callback);
}
@override
void dispose() {
widget.changeNotifier.removeListener(_callback);
super.dispose();
}
}

文档的这一部分是关于如何使用不同的参数重建您的小部件。

例如,对于StreamBuilder,首次构建可能类似于:

StreamBuilder(
stream: Stream.value(42),
builder: ...
)

然后有些事情发生了变化,StreamBuilder重建为:

StreamBuilder(
stream: Stream.value(21),
builder: ...
)

在这种情况下,stream改变了。因此,StreamBuilder需要停止听以前的Stream,听新的。

这将通过以下didUpdateWidget完成:

StreamSubscription<T> subscription;
@override
void didUpdateWidget(StreamBuilder<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.stream != oldWidget.stream) {
subscription?.cancel();
subscription = widget.stream?.listen(...);
}
}

相同的逻辑适用于ChangeNotifier和任何其他可观察对象。

最新更新