Flutter Riverpod的简单例子和指南

2,225 阅读7分钟

当我们开始使用Flutter时,我们使用了Flutter的最爱--供应商。通过这个项目,我们看到了所有的好处和问题,对于下一个项目,我们决定使用Riverpod。从那时起,它一直是我们的状态管理的选择。在这个简单的教程中,我们将创建一个简单的riverpod(1.0.4)使用的例子。如果你读过我以前的文章,你知道我欠你关于快速部署的新东西,但从那时起,我们的Flutter学院占用了我的时间,把我的注意力转移到这个上面,以帮助所有的学生。

步骤1.- 新项目和模拟数据

创建一个新的项目,并在根目录下添加一个数据文件夹(在这个例子中我们将使用json文件,但在这个实现之后,你可以很容易地将其切换为http调用或firestore)。你可以从这个链接中使用json,我们将在项目中使用。

为了使用和访问数据文件夹作为资产,你需要更新你的pubspec.yaml文件。

第二步。- 创建模型类

在lib目录下创建models文件夹,在那里我们将添加movie.dart文件,这将是我们的电影模型类。Flutter架构中的模型对应于MVC。当我们有相同类型的数据,我们期望收到的数据,通过一个模型来处理要容易得多(即使是意外的事情),因为它简化了工作。我们总是知道我们会得到什么,以何种形式得到,这将有助于我们通过应用来管理它。

  • 做到这一点的基本方法是定义一个类,并添加所有我们期待的变量,以及构造函数(在我们的案例中,今天也有标准的API格式),从JSON解析模型,也可以解析到JSON。
  • Json to dart应用程序的帮助下,如果我们有指定的JSON格式,它将为我们做所有的工作,所以不再多说,从movies.json列表中取一个JSON对象,并复制粘贴到json to dart应用程序。正如你所看到的,它甚至为我们处理了JSON对象中的数组数据(唯一的缺点是,它可能不是最新的dart版本,所以你可能需要调整代码,删除例如不必要的关键字等)。

步骤3.- 创建简单的视图

用部件创建一个简单的电影列表。我们提取了一个电影卡小部件,并添加了一个简单的列表视图构建器和一个电影类模型的例子。我们应该有这样的东西。这一步的代码在一个单独的分支中,所以你可以看到它。

第4步。- 引入Flutter Riverpod

首先,我们需要添加一个flutter riverpod包 ,你有一个安装指导,在给定的链接,然后做以下工作。

  • 一旦Riverpod安装完毕,我们就可以用一个ProviderScope来包装我们的根部件了。
  • ProviderScope是一个小部件,用于存储我们创建的所有提供者的状态。

之后,我们将把我们的StatelessWidget转换成Consumer widget。通过子类化ConsumerWidget,我们的widget的build()方法现在有一个额外的WidgetRef参数,我们可以用它来观察我们的提供者。

什么是WidgetRef?

Riverpod文档将WidgetRef定义为一个允许widget与提供者互动的对象。

为了更好地理解WidgetRef的目的是什么,让我们把它与BuildContext进行比较。

BuildContext让我们访问widget树上的祖先widget(比如Theme.of(context)和MediaQuery.of(context))。

换句话说,WidgetRef让我们访问任何我们想要的提供者。这是设计好的,因为所有的Riverpod提供者都是全局的。

正如我们将看到的,这有很多优点,让我们很容易地将任何状态管理逻辑移到widget树之外。状态可用性的例子。

好了,这个设置仍然与引入riverpod之前的工作方式相同,所以让我们创建我们的第一个提供者。

第5步。- 创建一个电影提供者

Provider和StateProvider对于简单的用例来说已经足够了,比如计数器的例子。但是在更复杂的应用程序中,我们经常需要在widget类之外存储一些状态和一些业务逻辑。

正因为如此,我们将为我们的业务逻辑使用StateNotifier Provider。

StateNotifierProvider是一个用于监听和公开StateNotifier(来自包state_notifier,Riverpod重新出口)的提供者。

StateNotifierProvider和StateNotifier是Riverpod推荐的解决方案,用于管理可能因用户交互而改变的状态。

所以我们需要一个不可变的状态,为了创建这个简单的方法,我们将使用一个叫做freezed的包。它所做的是为我们生成所有的模板代码,所以我们的提供者将是漂亮和干净的。

第一个简单的提供者将加载我们的json电影数据,看起来像这样(如果你只是复制粘贴,不要害怕丢失文件,要创建丢失的freezed文件,你需要运行freezed包说明中的一些命令)。

medium.com/media/d07c9…

我们现在也可以清理我们的main.dart文件,只需读取提供者,从列表中看到我们的电影。

第6步。- 添加简单的互动性

我们将添加一个简单的文本输入部件和onChanged函数触发器,我们将从提供者那里调用一个新的方法,称为filterMovies。

所以我们的main.dart现在看起来会是这样。

medium.com/media/1609b…

而出来的movie_provider.dart则是这样。

medium.com/media/5d740…

正如我们所看到的,虽然它是有效的,但我们有太多的重复代码,而且在搜索时没有加载器,当它是一个API请求时,会花费一些时间。

解决问题1:提取加载JSON的服务(以后可以很容易地在一个地方切换到http方法)。

medium.com/media/6f5fd…

并在提供者中取代获取。现在我们可以在一个地方轻松切换任何类型的数据获取方法。有了资源库(下一篇文章),它将很容易被测试。

解决问题2:在搜索中添加加载器

虽然这个问题可以用FutureProvider自然解决,但我们还是要用最简单的方法来解决这个问题。

  • 在MovieState中添加isLoading变量(每次加载都会触发)。

medium.com/media/1b20c…

  • 运行命令来重新生成电影状态

flutter packages pub run build_runner build - delete-conflicting-outputs

  • 并在主屏幕上观察isLoading的情况

medium.com/media/9159d…

给服务添加延迟,以模拟加载器。

也许这不是最理想的方法或代码,但我认为它对初学者是友好的,你可以在这个基础上建立,这是本文的目的。

完整的代码Repo可在github链接中找到。

为什么是Riverpod?

正如文档中所说,为了理解为什么我们需要Riverpod,让我们看看Riverpod解决了Provider的一些最常见的问题。

根据设计,Provider是对InheritedWidget的改进,它依赖于widget树

  • 组合Provider是非常冗长的
  • 按类型和运行时异常获取Providers

先进的Riverpod功能,我们将在未来谈论更多。

  • 自动处置修改器
  • 家族修改器
  • 使用Riverpod的依赖性重写
  • 用Riverpod组合提供程序
  • 提供者的范围

我个人认为,对于一个使用redux/vuex等网络背景的人来说,Riverpod是一种非常自然和合理的状态管理方式。Riverpod是一种非常自然和合理的状态管理方式,而且它的核心毕竟是Provider(Flutter的最爱),它是由同一个人做的。在这个简单的项目中,我们没有使用存储库,所以请记住这一点,在我写一篇扩展文章之前,请查看该模式的可测试性。


Flutter Riverpod的简单例子和指南最初发表在Dev Genius的Medium上,在那里人们通过强调和回应这个故事继续对话。