You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:51:00