Riverpod 3.0.0 版本中 Provider 类型选择指南

Riverpod 3.0.0(2025 年 9 月发布)是 Flutter 状态管理库的重大更新,简化了 API,引入了"mutations"功能(处理副作用,如加载/错误状态),统一了更新过滤机制(全部使用 == 比较),并默认支持自动重试失败的 provider。关键更新 :Riverpod 3.0.0 不再强制要求使用 @riverpod 注解和 riverpod_generator,可以直接编写 Notifier 类,减少 boilerplate 代码。旧版 provider(如 StateProviderFutureProvider 等)被标记为遗留(legacy) ,需从 flutter_riverpod/legacy.dart 导入,官方推荐迁移到基于 Notifier 的新 provider 类型。这些新类型更统一、可测试,且支持手动编写或代码生成(仍可选 @riverpod)。

选择 provider 时,考虑以下因素:

  • 同步 vs 异步:数据是立即可用(同步)还是需要等待(Future/Stream)?
  • 只读 vs 可变:状态是否需要外部修改?
  • 复杂逻辑:是否涉及业务规则、依赖注入或副作用?
  • 性能与清理 :是否需要 .autoDispose(自动销毁未使用的 provider)或 .family(参数化 provider)修饰符?

以下是 Riverpod 3.0.0 中推荐的 provider 类型及选择指南,遗留类型仅作迁移参考。内容基于官方文档和社区实践。

Riverpod 3.0.0 Provider 类型选择指南

主要 Provider 类型

Provider 类型 描述与用途 适用场景示例 优缺点简析
Provider 只读同步 provider,返回固定或计算值。不支持状态修改。 常量配置、简单计算(如字符串格式化)、依赖注入。 优点 :轻量、易缓存;缺点:不可变,无法处理异步。
NotifierProvider<T, Notifier> 可变同步状态,使用 Notifier 类管理内部状态。支持 state 更新。 计数器、表单输入、简单 UI 状态(如开关)。 优点 :简单、可测试;缺点:不适合复杂异步逻辑。推荐用于简单可变状态。
AsyncNotifierProvider<T, AsyncNotifier<T, T>> 可变异步状态,使用 AsyncNotifier 处理 Future 值。内置加载/错误/数据状态。 API 调用、数据库查询,需要更新异步数据。 优点 :统一处理异步(loading/error),支持 mutations;缺点:稍复杂。推荐用于大多数异步场景。
StreamNotifierProvider<T, StreamNotifier<T, T>> 可变流式状态,使用 StreamNotifier 处理 Stream 值。实时更新。 实时数据(如 WebSocket、动画流)、事件监听。 优点 :响应式流处理;缺点:仅限 Stream 数据。推荐用于实时更新。
遗留:StateProvider (从 legacy.dart) 简单可变状态(如字符串/整数)。不推荐。 临时简单状态(迁移时使用)。 优点 :快速;缺点:缺乏类型安全,官方弃用。迁移到 NotifierProvider。
遗留:FutureProvider (从 legacy.dart) 只读异步 Future 值。不推荐。 一次性异步加载(迁移时使用)。 优点 :简单异步;缺点:不可变、无内置重试。迁移到 AsyncNotifierProvider。
遗留:StreamProvider (从 legacy.dart) 只读流式 Stream 值。不推荐。 实时流(迁移时使用)。 优点 :流支持;缺点:不可变。迁移到 StreamNotifierProvider。
遗留:StateNotifierProvider<T, S> (从 legacy.dart) 复杂可变状态,使用 StateNotifier 类。不推荐。 业务逻辑类(如用户认证)。 优点 :强大;缺点:冗余。迁移到 NotifierProvider(简化版)。

如何选择 Provider?(决策流程)

  1. 数据是同步且只读?

    使用 Provider

    示例:

    dart:disable-run 复制代码
    final configProvider = Provider<String>((ref) => 'Hello');

    适用:静态配置、计算值。UI 中使用:final value = ref.watch(configProvider);

  2. 数据是同步且可变?

    使用 NotifierProvider

    示例:

    dart 复制代码
    class Counter extends Notifier<int> {
      @override
      int build() => 0;  // 初始状态
      void increment() => state++;  // 修改状态
    }
    final counterProvider = NotifierProvider<Counter, int>(() => Counter());

    适用:计数器、表单输入。UI 中使用:final count = ref.watch(counterProvider);

  3. 数据是异步(Future)且可能需要更新?

    使用 AsyncNotifierProvider

    示例:

    dart 复制代码
    class UserData extends AsyncNotifier<User> {
      @override
      Future<User> build(String userId) async {
        return await fetchUser(userId);  // 异步加载
      }
      Future<void> refresh() async => state = const AsyncLoading();  // 更新
    }
    final userProvider = AsyncNotifierProvider<UserData, User>((ref) => UserData());

    适用:API 调用、数据库查询。自动处理 AsyncValue(loading/data/error)。UI 中使用:final user = ref.watch(userProvider);

  4. 数据是流式(Stream)且实时更新?

    使用 StreamNotifierProvider

    示例:

    dart 复制代码
    class MessageStream extends StreamNotifier<List<Message>> {
      @override
      Stream<List<Message>> build() => firestore.collection('messages').snapshots();
    }
    final messageProvider = StreamNotifierProvider<MessageStream, List<Message>>((ref) => MessageStream());

    适用:实时数据(如 Firestore 流、WebSocket)。

  5. 复杂业务逻辑或副作用?

    使用 mutations (3.0 新功能)。

    示例:

    dart 复制代码
    final submitMutation = mutationProvider((ref, FormData data) async {
      await api.submit(data);
    });

    适用:表单提交、一次性操作,显示加载/错误状态而不中断 provider。

  6. 遗留类型?

    仅用于迁移旧代码,逐步替换为 Notifier 系列。@riverpod 注解可选,若使用可运行 flutter packages pub run build_runner build 生成代码。

最佳实践

  • 无需注解 :Riverpod 3.0.0 允许直接编写 Notifier/AsyncNotifier 类,无需 @riverpodriverpod_generator,但仍支持代码生成以减少 boilerplate。
  • 修饰符
    • .autoDispose:自动清理未使用的 provider,防止内存泄漏。
    • .family:参数化 provider(如 userProvider.family(userId))。
  • 测试:Notifier 类可独立测试,无需 Flutter 环境。
  • 性能 :更新过滤统一使用 ==,减少不必要重建。
  • 错误处理 :异步 provider 抛 ProviderException,支持自动重试。
  • 迁移:从 2.x 迁移时,替换遗留 provider,检查错误处理逻辑。
相关推荐
傅里叶1 小时前
Flutter项目使用 buf.build
flutter
恋猫de小郭3 小时前
iOS 26 开始强制 UIScene ,你的 Flutter 插件准备好迁移支持了吗?
android·前端·flutter
yuanlaile3 小时前
Flutter开发HarmonyOS鸿蒙App商业项目实战已出炉
flutter·华为·harmonyos
CodeCaptain4 小时前
可直接落地的「Flutter 桥接鸿蒙 WebSocket」端到端实施方案
websocket·flutter·harmonyos
stringwu5 小时前
Flutter 中的 MVVM 架构实现指南
前端·flutter
消失的旧时光-194317 小时前
Flutter 异步体系终章:FutureBuilder 与 StreamBuilder 架构优化指南
flutter·架构
消失的旧时光-194320 小时前
Flutter 异步 + 状态管理融合实践:Riverpod 与 Bloc 双方案解析
flutter
程序员老刘1 天前
Flutter版本选择指南:避坑3.27,3.35基本稳定 | 2025年10月
flutter·客户端
—Qeyser1 天前
Flutter网络请求Dio封装实战
网络·flutter·php·xcode·android-studio