Riverpod状态管理详解3 - provider与select

兄弟姐妹,哪位知道,Riverpod状态管理详解3 - provider与select
最新回答
撸管冠军╮

2026-07-29 20:18:13

Riverpod 的 select 机制通过选择性监听状态变化来优化性能。当使用 ref.watch(personStateProvider.select((p) => p.name)) 时,只有当 name 属性发生变化时,才会触发监听组件的刷新,从而避免不必要的重建。

  • select 的实现原理:

    select 方法返回一个 _AlwaysAliveProviderSelector 对象,该对象继承自 _ProviderSelector,并在其中实现了 addListener 方法。

    addListener 方法主要完成两部分工作:

    注册回调:在 stateProvider 中注册回调,当 state 改变时执行 _selectOnChange 方法。

    封装回调:将注册的回调封装为 _SelectorSubscription 对象,该对象最终返回到 widget 的 element 中,并保存在 _dependencies 中。

  • _selectOnChange 的处理逻辑:

    使用 select 的回调函数获取具体要监听的值(如 name 或 age),并将其包装成 Result 对象。

    比较旧值和新值,如果不同,则执行 listener(即 markNeedsBuild),触发组件刷新。

  • 状态变化流程:

    当 state 被重新赋值(如 age 增加 1)时,personProviderElement 执行 setState,进而触发 _notifyListeners。

    _notifyListeners 遍历所有监听器,执行 listener.listener,即 _selectOnChange。

    _selectOnChange 通过 select 回调获取新值,并比较新旧值。如果不同,则执行 listener(markNeedsBuild),触发组件刷新。

  • select 的本质:

    select 在 providerElement 和 WidgetElement 之间添加了一层过滤机制。providerElement._dependents 不再直接添加 WidgetElement.markNeedsBuild,而是通过 _AlwaysAliveProviderSelector._selectOnChange 判断是否需要执行 WidgetElement.markNeedsBuild。

通过这种方式,select 实现了对状态变化的精细控制,避免了因无关状态变化导致的组件不必要的刷新,从而提升了应用性能。