Compose重组的概念1

一、先给一句"硬核定义"(先放结论)

重组(Recomposition)= 当状态变化时,Compose 重新执行「受影响的 Composable 函数」,以计算新的 UI 描述

注意三点关键词:

  • 重新执行函数
  • 只执行受影响的部分
  • 不是重新创建整个界面

二、最重要的认知纠正(非常关键)

❌ 错误理解

"重组 = 重新绘制 View"

✅ 正确理解

重组 = 重新"算" UI,而不是重新"画" UI

Compose 的流程是:

text 复制代码
State 变化
   ↓
Recomposition(重新执行 Composable 函数)
   ↓
生成新的 UI Tree(描述)
   ↓
Diff
   ↓
真正需要的地方才重绘

三、一个最直观的例子(必须看)

kotlin 复制代码
@Composable
fun Counter() {
    Log.d("Counter", "Counter 执行")

    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("count = $count")
    }
}

日志行为

text 复制代码
首次进入页面
→ Counter 执行

点击按钮
→ Counter 执行

再点击
→ Counter 执行

👉 函数反复执行 = 重组


四、为什么 Compose 要"重组"?(本质原因)

因为 Compose 的核心哲学是

kotlin 复制代码
UI = f(State)
  • State 变了
  • 就必须重新算 f(State)

👉 这是声明式 UI 的必然结果


五、那「成功重组」到底是什么意思?

这是问的第二个重点 👇

"在每次成功重组后,执行同步操作(SideEffect)"

我们拆开解释。


1️⃣ 什么叫「成功重组」?

不是每一次函数执行都算"成功重组"。

成功重组 =

Compose 已经完成了一次状态 → UI 描述的更新,并且这次更新被提交

换句话说:

  • 新 UI Tree 计算完成
  • Diff 成功
  • 没有被中断 / 回滚

2️⃣ SideEffect 的执行时机(关键)

kotlin 复制代码
SideEffect {
    // 同步副作用
}

执行顺序是:

text 复制代码
Recomposition(函数执行)
   ↓
Compose 内部完成 UI 更新
   ↓
✅ SideEffect 执行

👉 SideEffect 永远不会在"中途"执行


六、为什么要"重组成功后"才执行 SideEffect?

因为 副作用是不可回滚的

比如:

kotlin 复制代码
SideEffect {
    systemUiController.setStatusBarColor(Color.Black)
}

如果:

  • UI 计算了一半
  • 又被新的状态打断

👉 如果这时执行副作用,就会产生 状态与 UI 不一致

所以 Compose 保证:

SideEffect 一定在 UI 状态已经稳定之后执行


七、SideEffect ≠ 初始化(很多人误用)

❌ 错误用法

kotlin 复制代码
SideEffect {
    viewModel.loadData() // ❌
}

原因:

  • 每次重组都会执行
  • 会重复触发

✅ 正确用途示例

kotlin 复制代码
SideEffect {
    Log.d("Compose", "当前 UI 状态已经同步")
}
kotlin 复制代码
SideEffect {
    window.statusBarColor = Color.Black
}

👉 让"外部世界"跟 UI 状态保持一致


八、重组 vs SideEffect 的"时间线图"(非常重要)

text 复制代码
State 变化
   ↓
Composable 函数重新执行(重组)
   ↓
Compose 内部应用 UI 更新
   ↓
✔ SideEffect 执行

⚠️ SideEffect 不参与 UI 计算


九、一个常见误解:重组是不是性能问题?

答案:不是

重组是常态,不是异常

真正的性能问题是:

  • 重组范围过大
  • 不必要的重组
  • 重组中做了重活

十、应该如何"正确看待重组"?

现在的角色转变很重要:

❌ "怎么避免重组?"

✅ "如何让重组只发生在该发生的地方?"

这也是:

  • derivedStateOf
  • 状态拆分
  • key 的意义所在

十一、给一句工程级总结(很重要)

重组不是 UI 的问题,而是 State 设计的问题


再给一句关于 SideEffect 的「精华版理解」

SideEffect 是"在 UI 已经稳定之后,对外部世界做同步动作"


相关推荐
stevenzqzq4 小时前
Compose 中最常用的布局** —— Box / Row / Column / ConstraintLayout教程
compose
stevenzqzq10 小时前
LaunchedEffect的作用和如何使用
compose
MengFly_2 天前
Compose案例 — Android 调用系统相机拍照
android·kotlin·compose
氦客2 天前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
氦客2 天前
UI编程的发展史 : 结合命令式UI和声明式UI
android·compose·声明式ui·ui编程·命令式ui·ui编程发展史·标记语言
stevenzqzq4 天前
Compose Navigation 时序图
compose
stevenzqzq4 天前
Compose 状态 / 协程 总图
compose
儿歌八万首7 天前
Jetpack Compose 动画实战:让你的 UI 动起来
android·kotlin·动画·compose
儿歌八万首10 天前
Jetpack Compose 自定义布局解析
kotlin·compose·自定义布局
zFox10 天前
二、Kotlin高级特性以及Compose状态驱动UI
ui·kotlin·compose