使用Riverpod Lint & Riverpod Snippets更高效的创建Flutter Apps

72d01feeb7764c72a3c10ac4063c75b7.png

点击上方蓝字关注我,知识会给你力量

5663d4ec5f00bbb38bbbdf3af01e984c.png

随着每一个新版本的发布,Riverpod 及其生态系统都在不断完善:

  • 核心软件包为反应式缓存和数据绑定提供了强大的应用程序接口

  • Riverpod Generator 软件包简化了学习曲线并带来了显著的可用性改进(我在这里已经介绍过了)

  • Riverpod Snippets扩展帮助我们轻松创建提供者和消费者

新的 Riverpod Lint 添加了许多有用的Lint和重构选项,让编写 Flutter 应用程序变得轻而易举。

等等...

还不止这些。

使用 Riverpod 进行现代开发是一件乐事,因为你只需编写少量代码,就能编写搜索和分页等复杂功能(让工具来指导你)。

在本文中,我将向你展示我是如何使用所有最新的好东西,包括代码生成、代码片段、重构选项和新的Riverpod lints,将我的时间跟踪应用程序重构为新的@riverpod语法的。

本文将展示 Riverpod Generator、Riverpod Lint 和 Riverpod Snippets extension 如何完美结合使用,但并不打算将其作为完整的资源。

添加所有必需的packages

由于我们将使用 Riverpod Generator 和 Riverpod Lint,因此需要在 pubspec.yaml 文件中添加一些packages:

dependencies:
  # the main riverpod package for Flutter apps
  flutter_riverpod:
  # the annotation package containing @riverpod
  riverpod_annotation:

dev_dependencies:
  # a tool for running code generators
  build_runner:
  # the code generator
  riverpod_generator:
  # riverpod_lint makes it easier to work with Riverpod
  riverpod_lint:
  # import custom_lint too as riverpod_lint depends on it
  custom_lint:

我们还需要在 analysis_options.yaml 中启用 custom_lint 插件:

analyzer:
  plugins:
    - custom_lint

接下来,我们需要在观察模式下启动 build_runner:

dart run build_runner watch -d

-d 标志是可选的,与 --delete-conflicting-outputs 相同。顾名思义,它可以确保我们覆盖先前构建中的任何冲突输出(这通常是我们想要的)。

这将监控项目中的所有 Dart 文件,并在我们进行修改时自动更新生成的代码。

现在设置已经完成,让我们来看一些代码。👇

使用Riverpod Generator 和 Riverpod Lint重构示例

假设我们有一个 AuthRepository 类,用来封装 FirebaseAuth 类:

// firebase_auth_repository.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class AuthRepository {
  AuthRepository(this._auth);
  final FirebaseAuth _auth;

  Stream<User?> authStateChanges() => _auth.authStateChanges();
}

假设我们也有这些providers:

// Make the [FirebaseAuth] instance accessible as a provider
final firebaseAuthProvider = Provider<FirebaseAuth>((ref) {
  return FirebaseAuth.instance; 
});

// Make the [AuthRepository] instance accessible as a provider
final authRepositoryProvider = Provider<AuthRepository>((ref) {
  return AuthRepository(ref.watch(firebaseAuthProvider));
});

// A [StreamProvider] for the [authStateChanges] stream
final authStateChangesProvider = StreamProvider.autoDispose<User?>((ref) {
  return ref.watch(authRepositoryProvider).authStateChanges();
});

如何将providers转换为新的 Riverpod 生成器语法?

添加prat文件

正如我们在关于 Riverpod Generator 的文章中所看到的,第一步是添加一个.part文件。

通过使用 Flutter Riverpod Snippets 扩展,我们只需键入几个字符即可:

66b417e9ed363edbad2ce29b8594e754.png

扩展会自动使用正确的文件名完成这一操作:

part 'firebase_auth_repository.g.dart';

转换一个简单的provider

接下来,让我们看看如何转换这个provider:

final firebaseAuthProvider = Provider<FirebaseAuth>((ref) {
  return FirebaseAuth.instance; 
});

同样,我们可以从输入 riverpod 开始,得到一个选项列表:

a43ae4ccdd9c19e0f483b29f4afe2f0e.png

在决定选择哪个选项时,我们可以问自己

  • 这个provider会返回一个对象、一个 Future、一个流还是一个 Notifier?

  • 当不再被监听时,它应该自行处置,还是继续存活?

由于 FirebaseAuth 是一个在整个应用生命周期中都保持存活的单例,因此我们可以选择 riverpodKeepAlive 选项,最后得到如下结果:

c22d4f54bd66393d2702ce4c20016ce4.png

下一步是在空白处添加

  • 返回类型

  • 函数名称

  • 添加其它附加参数(本例中没有)

  • provider主体功能

这就是我们的最终结果:

@Riverpod(keepAlive: true)
FirebaseAuth firebaseAuth(Ref ref) { // Stateless providers must receive a ref matching the provider name as their first positional parameter.dart(stateless_ref)
  return FirebaseAuth.instance;
}

这段代码几乎是正确的。但 Riverpod Lint 提醒我们必须使用正确的类型,因为生成器会为每个provider创建特定的 Ref 类型。

事实上,函数名称(firebaseAuth)与生成的 Ref 类型和provider名称之间有严格的关系:

  • firebaseAuth() → FirebaseAuthRef 和 firebaseAuthProvider

因此,让我们再次使用 “快速修复”:

11ab45daa49feb46ca32024aefb8e0ce.png

然后就好了!Lint警告就消失了:

@Riverpod(keepAlive: true)
FirebaseAuth firebaseAuth(FirebaseAuthRef ref) {
  return FirebaseAuth.instance;
}

只要 build_runner 仍在观察模式下运行,就会生成一个 firebaseAuthProvider(在 part 文件中),并可在我们的代码中使用。

重构其余provider

接下来,我们还需要重构其余两个provider:

// Make the [AuthRepository] instance accessible as a provider
final authRepositoryProvider = Provider<AuthRepository>((ref) {
  return AuthRepository(ref.watch(firebaseAuthProvider));
});

// A [StreamProvider] for the [authStateChanges] stream
final authStateChangesProvider = StreamProvider<User?>((ref) {
  return ref.watch(authRepositoryProvider).authStateChanges();
});

在 Riverpod Snippets 和 Riverpod Lint 的帮助下,这很容易做到:

@Riverpod(keepAlive: true)
AuthRepository authRepository(AuthRepositoryRef ref) {
  return AuthRepository(ref.watch(firebaseAuthProvider));
}

@riverpod
Stream<User?> authStateChanges(AuthStateChangesRef ref) {
  return ref.watch(authRepositoryProvider).authStateChanges();
}

请注意,我选择在 firebaseAuthProvider 和 authRepositoryProvider 中使用 keepAlive,但没有在 authStateChangesProvider 中使用 keepAlive。这是有道理的,因为前两个provider包含长期依赖关系,而第三个provider可能需要也可能不需要始终监听。

示例 生成 AsyncNotifier

除了为objects, futures, 和 streams创建provider外,我们还想为 Notifier 和 AsyncNotifier 等类生成provider。

例如,下面是我的项目中的 AsyncNotifier 子类:

class EditJobScreenController extends AutoDisposeAsyncNotifier<void> {
  @override
  FutureOr<void> build() {
    // omitted
  }

  // some methods
}

我本可以手工转换。

不过,Riverpod Snippets 提供了方便的 riverpodAsyncClass 和 riverpodClass 选项,再次帮助了我们:

39a4d742c401d9904c7ecc1c52e08aec.png

选择上述选项后,我们就得到了这样的代码:

77959afeb51b00402dd572068e08d275.png

然后,我们就可以填补空白了:

@riverpod
class EditJobScreenController extends _$EditJobScreenController {
  @override
  FutureOr<void> build() {
    // omitted
  }
}

Riverpod Lint 还能做什么?

上面的示例展示了如何将现有provider或notifiers转换为新语法。

但你还可以用Riverpod Lint做更多事情,包括:

  • 从StatelessWidget转换为ConsumerWidget或ConsumerStatefulWidget

  • 在functional 和 class variants 之间转换

请再次查看官方文档,了解完整的选项列表。

总结

在 Riverpod 的早期,选择正确的provider并使用正确的语法很困难(尤其是在处理带有参数的复杂provider时)。

但正如我们所见,Riverpod Generator 和 Riverpod Lint 让我们的工作变得简单多了。

如今,将任何provider转换为新的 @riverpod 语法只需以下步骤:

  • 使用 Riverpod Snippets 扩展添加part文件

  • 选择正确的provider(同样使用 Riverpod Snippets)

  • 填写空格(返回类型、函数名和参数)

  • 选择正确的 Ref 类型(Riverpod Lint 简化了这项工作)

完成这些后,我们就可以保存文件,然后 build_runner 就会处理剩下的工作。

本文翻译自:https://codewithandrea.com/articles/flutter-riverpod-lint/#adding-all-the-required-packages


向大家推荐下我的网站 https://www.yuque.com/xuyisheng  点击原文一键直达

专注 Android-Kotlin-Flutter 欢迎大家访问

往期推荐

本文原创公众号:群英传,授权转载请联系微信(Tomcat_xu),授权后,请在原创发表24小时后转载。

< END >

作者:徐宜生

更文不易,点个“三连”支持一下👇

  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值