第1章 State Hoisting 核心概念

State Hoisting(状态提升)是 Jetpack Compose 和 MVVM 架构的基石——将状态从可变的局部 UI 提升到最近的共同父级(即 ViewModel),使 UI 成为纯函数,状态可预测、可测试、可复用。本章从定义、职责边界、数据流原则三个维度建立核心认知,并给出架构边界、信任链路与落地验收框架。

1.1 状态提升的定义

状态提升指将组件的内部可变状态移到父级或外层持有者,父级以只读方式下发状态,子级通过回调上报用户意图。在 MVVM 中,ViewModel 就是那个“父级”。

维度说明
状态共享多个 UI 组件可读取同一份 ViewModel 状态,避免同步问题
单向数据流状态只能向下传递,事件只能向上传递
可预测性状态变化路径唯一,便于调试和回溯
架构边界提示:State Hoisting 的边界是 ViewModel 层,UI 层不得持有可变状态(局部动画等临时状态除外)。信任链路:View → ViewModel → Repository → DataSource,每层只信任下一层返回的数据。

1.2 与 ViewModel 职责边界

角色职责不可推卸责任
View渲染状态、上报事件、动画协调不得维护业务状态、不得直接修改 Model
ViewModel持有提升状态、处理业务逻辑、转换数据不得持有 UI 引用、不得感知生命周期(除 clear 外)
Model数据持久化、网络请求、本地存储不感知 ViewModel 和 View

ViewModel 是状态提升的唯一合法容器。所有StateFlow、LiveData、mutableStateOf 必须声明在 ViewModel 作用域内。UI 层只能通过 .collectAsState() 或 .observe() 订阅只读状态。

常见风险点:将状态提升到 ViewModel 之外的全局单例(如静态 object),会导致测试困难、生命周期泄漏、线程安全问题。信任链路必须终止于 ViewModel,不可越级。

1.3 单向数据流原则

单向数据流(UDF)是 State Hoisting 的运行规则:

  • 数据流(白色箭头):Model → ViewModel → View,状态不可变且向下流动
  • 事件流(深色箭头):View → ViewModel → Model,用户动作以事件形式向上传播
  • 控制流:ViewModel 是唯一决策者,决定何时触发数据刷新、如何处理副作用

以下代码片段展示了 Compose 中典型的 UDF 模式:

// ViewModel
class MyViewModel : ViewModel() {
    private val _state = MutableStateFlow(MyUiState())
    val state: StateFlow<MyUiState> = _state.asStateFlow()

    fun onButtonClick() {
        _state.update { it.copy(loading = true) }
        // 触发 repository 等异步操作
    }
}

// View (Composable)
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.state.collectAsState()
    Button(onClick = { viewModel.onButtonClick() }) {
        Text(if (uiState.loading) "加载中…" else "点击")
    }
}

状态 uiState 由 ViewModel 提升维护,UI 只读取并触发事件。整个信任链路清晰:UI 不信任自己维护的状态,只信任 ViewModel 下发的不可变快照。

架构选型权衡

方案优势劣势
State Hoisting + ViewModel可测试、可复用、生命周期安全增加 ViewModel 类数量,小型界面略显繁重
局部状态(Composable 内 remember)简单快速无法跨组件共享、难以测试、生命周期耦合
全局单例状态跨页面共享方便内存泄漏、线程竞争、测试困难
验收标准(第1章)
✅ 项目中每个业务界面至少有一个 ViewModel 承担状态提升职责
✅ UI 代码中不出现 MutableStateFlow、mutableStateOf 等可变声明
✅ 事件处理函数全部定义在 ViewModel 内,UI 仅调用方法
✅ 可通过替换 ViewModel 实现(测试替身)验证单向数据流正确性
State Hoisting 在 MVVM 中的分层与数据流 View(UI 组件) ViewModel(状态提升) Repository DataSource(本地/远程) 数据流 事件流 状态提升边界

图 1-1 State Hoisting 在 MVVM 中的分层与双向数据流示意。实线为数据流,虚线为事件流,黄色虚线框标识提升边界。