Flutter Riverpod优化:避免重复传递uid参数
如何让带uid参数的Riverpod Provider无需重复传参即可访问,且避免重复获取数据?
我定义了一个接收uid参数的CurrentUser Riverpod类,在应用校验用户认证状态时初始化该Provider。现在希望无需每次传递uid就能watch或read此Provider;同时希望不传递uid时,build方法无需重新获取数据,直接使用当前状态。请问这是否可行?
@Riverpod(keepAlive: true) class CurrentUser extends _$CurrentUser { @override Future<User> build({required String uid}) async { return await ref.read(firestoreRepoProvider).getUser(uid: uid); } //...other methods to mutate state }
可行,推荐两种实现方案
方案一:用独立Provider存储当前认证UID,让CurrentUser依赖它
这种方式最贴合需求,无需每次传参,且只有UID变化时才会重新获取数据。
- 先创建一个用于存储当前已认证用户UID的StateProvider:
final currentAuthUidProvider = StateProvider<String?>((ref) => null);
- 修改
CurrentUserProvider,移除uid参数,改为从currentAuthUidProvider读取UID:
@Riverpod(keepAlive: true) class CurrentUser extends _$CurrentUser { @override Future<User?> build() async { final uid = ref.watch(currentAuthUidProvider); if (uid == null) return null; // 只有当uid变化时,才会重新执行此方法获取数据 return await ref.read(firestoreRepoProvider).getUser(uid: uid); } // 保留你的状态修改方法,比如更新用户信息 Future<void> updateUser(User updatedUser) async { await ref.read(firestoreRepoProvider).updateUser(updatedUser); // 手动触发状态刷新 ref.invalidateSelf(); } }
- 在认证校验完成后(比如登录成功时),更新
currentAuthUidProvider的状态:
// 示例:登录成功后设置UID ref.read(currentAuthUidProvider.notifier).state = authenticatedUser.uid;
之后在任何地方需要访问当前用户数据,直接调用ref.watch(currentUserProvider)即可,无需传参。而且只要UID不变化,build方法就不会重复执行,直接复用之前的状态。
方案二:保留Family参数但结合缓存(不推荐)
如果你坚持要保留uid参数的形式,可以用Riverpod的Family,但需要额外处理缓存逻辑,不如方案一简洁:
@Riverpod(keepAlive: true) class CurrentUser extends _$CurrentUser { String? _cachedUid; Future<User>? _cachedUser; @override Future<User> build({required String uid}) async { // 如果当前UID和缓存的一致,直接返回缓存的Future if (_cachedUid == uid && _cachedUser != null) { return _cachedUser!; } _cachedUid = uid; _cachedUser = ref.read(firestoreRepoProvider).getUser(uid: uid); return _cachedUser!; } }
但这种方式需要手动维护缓存,而且每次访问还是要传uid,不如方案一省心。
内容的提问来源于stack exchange,提问作者wolfeweeks
相关产品推荐
相关产品推荐

