0
点赞
收藏
分享

微信扫一扫

2021 年的 Flutter 状态管理:如何选择?

有时候选择比较少也是一件好事,例如在 ​​React​​​ 中通常只盛行一到两个状态管理解决方案,而​​Flutter​​ 自从 2020 年末开始,每个月似乎都有新的状态管理方案出现,因此这里主要罗列出它们的一些优劣,从而帮助你选择最适合的状态管理方案。

基础

一般在无需修改 ​​pubspec.yaml​​文件的情况下,你默认有两种状态管理解决方案可以选择,大多数时候这就足够了。

setState

2021 年的 Flutter 状态管理:如何选择?_flutter

​setState​​​ 仅在本地范围内有效,如果一个 ​​Widget​​​ 需要改变它自己的状态,那么 ​​setState​​ 就是你最好的选择。

例如:修改开关是打开还是关闭,或者存储改变正在输入的文本内容,这种场景你真的不需要考虑任何其它状态管理包

我的经验法则是:如果只在此 Widget 中需要有状态变量,或者在该控件树下恰好只有 1 个上下的 ​Widget​,则它属于本地范围,这时候直接使用 ​StatefulWidget​ 是最合适不过。

如果你需要将状态在控件树内向下传递树,那么只需将变量放在子 ​​Widget​​​ 的构造函数中;如果相同的变量需要传递到 2+ ​​Widget​​ 的构造函数,那么这时候才需要研究更高范围的状态管理。

InheretedWidget

前面我们在 ​​setState​​ 中讨论的那个开关,如果它是控制应用是处于暗模式还是亮模式,如果在这种情况下,你就需要将状态提升到可以更好地沿控件树传播的某个位置。

而在你使用第三方框架去完成这个需求时,让我们看一下 ​​InheretedWidget​​ 。

​InheretedWidget​​​ 允许它下面的任何 ​​Widget​​ 访问它的属性,这意味着可以有一个变量,例如:

enum Theme {
dark,
light
}

在 ​​InheretedWidget​​​ 内部,任何与主题有关的 ​​Widget​​​ 都可以通过 ​​MyInheretedWidget.of(context).theme​​​ 访问主题,并且该​​Widget​​ 还会在主题更新时自动重建。

直接使用 ​​InheretedWidget​​​ 不好的地方在于会有很多样板,​​Widget​​ 系统有大量重复的代码。

你需要安装的那些

BLoC (Cubit?)

​Bloc​​​ 可能是 Flutter 中状态管理最古老的解决方案之一(不考虑 ​​scoped_model​​ 的话),并且现在看来仍然还不错。

最近 ​​BLoC​​​ 已将 ​​Cubit​​​ 添加到组合中,这使得 ​​BLoC​​​ 或多或少不会显得过气,因为 ​​Cubit​​​ 降低了所需的样板,这意味着以后迁移更容易,而在我看来 ​​BLoC​​ 在这两个不同的领域中表现出色:

1、与团队合作

​BLoC​​ 在 不灵活 方面做得非常好,可能对于很多人来说这是一件坏事:他们希望能更快速地更改他们的应用,而无需编写或更改太多代码。

但是对于团队来说情况并非如此:通过让事情变得不灵活,你可以保证一切都按照最初开发人员的预期工作——例如 ​​BLoC​​​ 中的状态仅仅有 1、2 和 3 这样的值,你在使用 ​​BLoC​​ 更改为这些值时,其他程序员不会意外地将其值移动到 4,这就是它不灵活的好处。

1、事件驱动状态

​BLoC​​​ 是基于事件驱动的,你必须定义你的事件,执行 API 调用可能会触发一个事件,该事件会推出一个  ​​CallingAPIState​​​ 的 state,然后当 API 调用完成时,它会推出一个​​HaveAPIResultsState​​.

如果你想严格定义你的事件和状态,那么 BLoC 很适合你,如果你需要灵活性和开发速度,那么 ​BLoC​ 可能不是正确的选择。

Provider

2021 年的 Flutter 状态管理:如何选择?_Android_02

出于遗留原因这里将 ​​Provider​​ 列入介绍,它很简单,很干净,很棒……但有一些缺陷和改进的余地。

将 ​​Provider​​​ 视为 ​​InheretedWidget​​​ 使用可以减少样板文件,事实上 ​​Provider​​​ 是建立在 ​​InheretedWidget​​ 之上,它只是减少了你需要编写的代码量。

如果你的应用已经在使用 ​​Provider​​,那么你可以继续使用它,这是一个非常好的状态管理包,没有理由需要迁移到另一个解决方案。

但是它还有一些改进的余地,我认为 ​RiverPod​Provider​ 有改进余地的地方做得更好

RiverPod

2021 年的 Flutter 状态管理:如何选择?_ide_03

在 ​​RiverPod​​​ 的网站上可以看到,他们称自己为“​​Provider​​,但与众不同”。

这样的形容很贴切,​​Provider​​​ 即使削减了很多的模版,但仍然有一些是可以进一步减少的。此外​​Provider​​​ 依赖于 ​​BuildContext​​​——我认为在很多情况下这确实很棒(它会迫使你使用 ​​Widget​​​ 树),但有时就像应用的生命周期一样,在任何的地方获取 ​​BuildContext​​ 是不切实际的。

​RiverPod​​​ 在 ​​Provider​​ 的优点上改进如下:

  • Provider 更少的样板:​​RiverPod​​​ 在减少​​Provider​​ 模版方面做得很好,允许开发者只注册一个顶级存储而不必单独提供每个提供。(可能有人一想到把所有东西都集中在一个地方而畏缩——别担心,你可以确定你的 pod。)
  • 不依赖​​BuildContext​​​:这也是一个很好的选择,原因前面已经提到。有时你只是无法在需要的地方获得​​BuildContext​​。
  • 编译安全:到目前为止这是状态管理的最佳创新,只要代码能编译就是安全的,我们不再需要知道为什么不能在树中找到我们的​​Provider​​ , 这是一项巨大的创新,可以为你节省很多的时间。

​RiverPod​​​ 只是 ​​Provider ​​​的不同皮肤——但是它是更光滑、更好的皮肤,如果您正在启动一个新应用并想使用 ​​Provider​​​ ,我强烈建议你考虑 ​​RiverPod​​。

其他

以下是在考虑状态管理的时候调研过的方案,但最终没有使用:

  • ​GetX​​:我不是 ​​GetX​​ 的粉丝,​​GetX​​ 试图完成很多工作,但这限制了你的灵活性,如果你希望有“完整应用场景” 的第三方包,那么 ​​GetX​​ 是你的最佳选择没,我对此尝试过接入,但不喜欢它。
  • ​get_it​​:​​get_it​​ 不是一种状态管理方案——但大家一直在使用它,如果用作状态管理方案来看,它会非常混乱。
  • ​redux​​ / ​​fish_redux​​ / ​​mobx​​:这些都来自 ​​React​​,并且具有非常相似的风格——但我认为 ​​React​​ 和 ​​Flutter​​ 是两个看起来相似却不同的框架,如果你习惯了它们,那么你可以使用它们,但在我看来,为 ​​Flutter​​ 设计的状态管理框架更为干净。
举报

相关推荐

0 条评论