Flutter 极简状态管理:基于 ValueNotifier 实现
在 Flutter 开发中,状态管理方案的选择往往让开发者感到困惑。从 Stacked、Provider、Bloc 到全能的 GetX,从 web 端过来的 Redux、Mobx、Signal,再到最近很火的 Provider 的亲兄弟 Riverpod,各种方案都有其独特的优势和适用场景,但每一种都有一些地方让我难以理解或认同,要么规定了很多骚操作,要么模板代码太多,要么背后隐藏着太多 “魔法”,而我需要的是简单易懂、尽可能简洁、可扩展的方案。
于是便有了这篇文章,我要介绍一种不使用第三方状态管理方案的方法,它唯一用到的第三方包是 GetIt(但不是用于管理状态,而是依赖注入管理),而对于状态改变时重建 UI,会使用 Flutter 自带的 ValueNotifier
和 ValueListenableBuilder
类。
为什么不使用第三方状态管理方案?
我不是劝大家放弃正在使用的第三方状态管理方案,如果当前用着顺手就没必要改变。 我在不同的项目里也会选择不同的第三方状态管理方案,比如 Provider、GetX、Riverpod,我都有在项目中实际用过,不是说他们不好,这取决于项目的需求和个人的偏好。
我有的时候就不想选择第三方状态管理方案,主要考虑了以下几个主要原因:
- 复杂性与学习成本
- 第三方状态管理库通常具有复杂的概念和使用方式。例如,一些库引入了大量的抽象概念和设计模式,如 Redux 的单向数据流和多个中间件的概念,这对于初学者来说理解和掌握起来较为困难。
- 学习和使用这些库需要花费大量的时间和精力去理解其内部机制、各种概念之间的关系以及如何正确地应用它们。这可能会导致开发周期延长,尤其是在项目初期需要快速搭建原型和实现基本功能时。
- 项目的依赖管理
- 引入第三方库会增加项目的依赖关系。不同的第三方库可能存在版本兼容性问题,当需要更新某个库时,可能会引发一系列的依赖冲突,需要花费额外的时间和精力去解决。
- 过多的依赖也会增加应用的体积和构建时间,这对于移动应用来说是需要考虑的重要因素,尤其是在应用需要在资源有限的设备上运行时。
setState
不够用吗?
Flutter 本身提供了一些基本的状态管理方式,如setState
方法,对于简单的应用场景,开发者可以快速上手,通过在StatefulWidget
中调用setState
来更新 UI,这种方式直观且易于理解。
但是,对于复杂的应用场景,setState
无法满足需求。例如,当应用具有多个页面和复杂的状态交互时,使用setState
可能会导致代码结构混乱,难以维护。
随着应用的不断发展和功能的增加,setState
无法很好地适应新的需求,缺乏足够的扩展性和灵活性来处理复杂的业务逻辑和状态转换。
最重要的是每次调用 setState
都会触发 UI 的重建,这可能会导致性能问题,尤其是在复杂的 UI 结构中。
所以,setState
通常用于更新局部状态,而不是全局状态。并且setState
通常与 UI 逻辑耦合,难以进行单元测试。