写在前面
本文中提及的use
开头的函数,都出自与我的 ComposeHooks 项目,它提供了一系列 React Hooks 风格的状态封装函数,可以帮你更好的使用 Compose,无需关系复杂的状态管理,专心于业务与UI组件。
这是系列文章的第四篇,前文:
什么是 MVI?
什么是 MVI
?想必你也看过很多博客了,其实简单说就是:明确分离数据模型(Model)、用户界面(View)和用户意图(Intent,也称为事件、动作),以实现UI的响应式和可预测的更新。
它与 MVVM
其实区别不大,有别于 MVVM 的是,MVVM 将耦合代码按照职责区分,拆分文件。借助 LiveData
或者 DataBinding
将 VM 中数据更新直接驱动 V 层,实现了 V 层与 M 层之间的解耦。
得力于 Compose 带来的状态驱动视图能力,我们可以理解 MVI 思想为:用户发出事件,事件驱动状态变化,状态驱动 UI 变化。这也就是所谓的事件向上,状态向下:事件从组件发出,单一可信来源的状态驱动组件更新。
从这一思想出发,我们可以理解为:谁持有状态,谁就是 M 层。那么过去的 MVVM 的文件拆分将会变得相对松散,我们完全可以摒弃过去那种全屏式思想,不再根据屏幕创建一个 VM 大管家。而是拆分成职责、粒度更细小的组件思想。
当然使用 MVVM
我们一样可以做到类似的效果,但是 MVI 将它流程化、标准化,所以可以理解为其实 MVI 就是一个有一定模板的更优秀的 MVVM
。
过去我们的 VM 层其实也很重,一个复杂的页面,数个网络接口,都被仍在一个 VM 中,鉴于不同开发者的水平的参差,我们项目中甚至有一个 VM 文件中持有了20多个 LiveData,可以说完全违背了 MVVM 的初衷。
同样的,想必你已经看了很多在 Compose 中使用 ViewModel
来实现 MVI
的文章了吧(我甚至看过回字的四种写法),它真的有这么复杂么?在 Compose 中我们还需要这样的一位大管家么?虽然很多例子、甚至官方的 demo,都还在使用 ViewModel
,但是这是一种无法回避的取舍?还是既往路线的惯性。
在一些场景下,我们完全可以更组件化思维,在更小粒度上应用 MVI。今天你可以试试一点新东西:useReducer
,通过它我将进一步阐述我所说的:松散的、组件下的 MVI 思想。