Riverpod中read先于watch调用后状态未销毁的疑问
关于Riverpod中read与watch状态保留的疑问
页面Widget代码
@override void initState() { super.initState(); ref .read(disableTimeControllerProvider.notifier) .initStateWhenCreate(widget.watchId); } @override Widget build(BuildContext context) { ClassMode classModeState = ref.watch(disableTimeControllerProvider); }
Provider代码
@riverpod class DisableTimeController extends _$DisableTimeController { @override ClassMode build() { return ClassMode(); } void initStateWhenCreate(String watchId) { ClassMode classMode = ClassMode( watchId: watchId, classSwitch: 1, //默认开启 classWeek: 31, holidaySwitch: 1, timePeriod: [ClassModeTime(startTime: "08:00:00", endTime: "11:30:00")], type: 0, ); state = classMode; } }
疑问
我在Widget中先调用read初始化状态,之后才用watch监听。按逻辑,无人监听时read创建的状态应立即销毁,但后续watch却能获取到read修改后的状态。想请教该现象的原因,以及read会将状态保留多久?
原因解析
你的场景里,initState调用read时确实会创建Provider的状态,但Riverpod的状态销毁不是立即触发的,而是设有一个延迟周期。这个延迟是为了应对组件重建、快速切换页面等场景,避免频繁创建销毁状态带来的性能浪费。
你这里initState执行后很快进入build方法调用watch,此时状态还没到销毁的延迟时间,所以watch能直接复用之前被read创建并修改过的状态。
read的状态保留时长
- 默认情况下,未被监听的Provider状态会在最后一个监听者取消监听后的60秒被销毁(这个时长可通过
ProviderContainer的disposeDelay参数自定义)。 - 如果在延迟周期内有新的监听者(比如你的
watch)注册,状态会被保留,不会触发销毁。 - 若超过延迟周期仍无新监听,状态才会被彻底销毁,下次调用
read或watch时会重新执行build方法创建新状态。
内容的提问来源于stack exchange,提问作者zx l
相关产品推荐
相关产品推荐

