关于 riverpod-family
Riverpod Family 技能介绍如何让一个 provider 按参数组合维护彼此独立的状态,适用于依赖 ID、查询或页码的数据请求。内容涵盖创建、使用、自动销毁及测试覆盖。
主要功能
- 01按参数维护独立状态
- 02支持函数式与 Notifier provider
- 03介绍自动销毁配置
- 04说明参数相等性要求
- 05讲解测试中的 provider 覆盖
适用场景
- 01按用户 ID 加载不同用户数据
- 02按查询条件或页码请求 API
- 03测试时覆盖指定参数的 provider
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ serverpod/ skills-registry --skill riverpod-family安装后在 Claude Code 中输入/riverpod-family确认已加载。
详细介绍
Riverpod — Family
说明
Family 让单个 provider 拥有多个相互独立的状态,每种参数组合对应一个状态(类似于以参数为键、状态为值的 Map)。适用于依赖 ID、查询或页码的 API 调用。
创建 Family(函数式)
添加 .family,并为参数增加一个类型参数。provider 函数接收 (ref, param):
final userProvider = FutureProvider.autoDispose.family<User, String>((ref, id) async {
final dio = Dio();
final response = await dio.get('https://api.example.com/users/$id');
return User.fromJson(response.data);
});
使用代码生成时,在函数中添加参数;生成的 provider 可接受参数:userProvider(id)。
创建 Family(Notifier)
使用 NotifierProvider.family / AsyncNotifierProvider.family(以及 .autoDispose.family)。Notifier 必须有一个用于存储参数的构造函数:
final userProvider = AsyncNotifierProvider.autoDispose.family<UserNotifier, User, String>(
UserNotifier.new,
);
class UserNotifier extends AsyncNotifier<User> {
UserNotifier(this.id);
final String id;
@override
Future<User> build() async {
final dio = Dio();
final response = await dio.get('https://api.example.com/users/$id');
return User.fromJson(response.data);
}
}
使用 Family
在 watch 或 read 时传入参数:
final user = ref.watch(userProvider('123'));
final other = ref.watch(userProvider('456')); // independent state
参数必须具有一致的 == 和 hashCode。不要使用可变对象或列表/映射字面量作为参数(例如,ref.watch(myProvider([1,2,3])) 是错误的,因为 [1,2,3] != [1,2,3])。建议使用基本类型或实现了 ==/hashCode 的自定义类。启用 riverpod_lint 的 provider_parameters 规则以捕获错误。
使用 Family 时自动释放
使用 Family 时启用自动释放,这样当某个参数不再使用时(例如,用户离开页面),就可以释放该参数对应的状态,避免缓存无限增长。
在测试中覆盖
- 覆盖单个参数:向 override 传入相同的参数。
- 覆盖所有参数:使用忽略参数或返回固定值的 provider 进行覆盖。确切语法请参阅 riverpod-overrides 和文档。
评论
支持 Markdown