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

为何、何时及如何使用RiverpodGenerator?对比CRUD+模型方案

为什么要用RiverpodGenerator和Freezed?

先聊Freezed:
手动写数据模型时,你是不是总在重复写copyWith、toString、==这类方法?不仅麻烦,还容易漏字段或者写错逻辑。Freezed就是帮你自动生成这些样板代码的工具,而且它天生支持不可变对象——这对状态管理至关重要,能避免意外修改数据导致的隐性bug。另外,Freezed的密封类(sealed class)可以轻松实现状态的多分支处理,比如请求数据时的「加载中/成功/失败」三种状态,不用手动写一堆嵌套if-else,代码逻辑会清晰很多。

再讲RiverpodGenerator:
Riverpod本身是个灵活的状态管理库,但手动写Provider(比如StateNotifierProvider、AsyncNotifierProvider)时,要写不少重复代码:定义Provider实例、关联Notifier、处理类型参数……RiverpodGenerator用注解(比如@riverpod)就能自动帮你生成这些代码,不仅减少手写量,还能避免类型不匹配这类低级错误。同时,它还能自动处理依赖关系,让你的状态管理代码更简洁、更易维护。

RiverpodGenerator的适用场景
  • 中大型项目:当你的状态数量多、依赖关系复杂时,Generator能大幅减少样板代码,降低维护成本,避免代码冗余。
  • 需要处理异步状态的场景:比如网络请求、本地数据库操作,用AsyncNotifier结合Generator,能自动帮你管理「加载中/成功/失败」的状态,不用手动维护状态枚举。
  • 团队协作项目:统一状态管理的写法,减少不同成员的代码风格差异,新人上手更快。
  • 嫌手动写Provider麻烦的场景:如果你觉得手动创建Provider的步骤繁琐,Generator能让你用几行注解搞定原本十几行的代码。
如何使用RiverpodGenerator
  1. 添加依赖:在pubspec.yaml中添加以下依赖:
dependencies:
  riverpod_annotation: ^2.3.0

dev_dependencies:
  riverpod_generator: ^2.3.0
  build_runner: ^2.4.0
  1. 定义Notifier类:用@riverpod注解你的Notifier,Generator会自动生成对应的Provider。比如实现一个待办列表的状态管理:
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'todo_list.g.dart';

@riverpod
class TodoList extends _$TodoList {
  // 初始化状态
  @override
  List<String> build() {
    return [];
  }

  // 添加待办的方法
  void addTodo(String todo) {
    state = [...state, todo];
  }

  // 删除待办的方法
  void removeTodo(String todo) {
    state = state.where((item) => item != todo).toList();
  }
}
  1. 生成代码:运行build_runner命令生成对应的Provider代码:
# Flutter项目
flutter pub run build_runner build

# Dart项目
dart run build_runner build
  1. 在UI中使用:通过ref.watch监听状态,通过ref.read调用Notifier的方法:
// 监听待办列表状态
final todos = ref.watch(todoListProvider);

// 添加待办
ElevatedButton(
  onPressed: () {
    ref.read(todoListProvider.notifier).addTodo("新的待办");
  },
  child: const Text("添加待办"),
)
  1. 结合Freezed优化状态:如果需要处理异步状态,比如从网络加载数据,可以用Freezed定义密封类状态,再结合Generator:
// 用Freezed定义状态
@freezed
class TodoState with _$TodoState {
  const factory TodoState.loading() = _Loading;
  const factory TodoState.success(List<Todo> todos) = _Success;
  const factory TodoState.error(String message) = _Error;
}

// 用Generator定义AsyncNotifier
@riverpod
class TodoRepository extends _$TodoRepository {
  @override
  TodoState build() {
    return const TodoState.loading();
  }

  Future<void> fetchTodos() async {
    try {
      final todos = await api.fetchTodos();
      state = TodoState.success(todos);
    } catch (e) {
      state = TodoState.error(e.toString());
    }
  }
}

内容的提问来源于stack exchange,提问作者Mohammed M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:45:26