前言
在 Jetpack Compose 中,组件(@Composable
函数)的重新渲染(即重组)是由其依赖的状态变化触发的。
重组触发条件
具体触发时机可以总结为以下几种情况:
依赖的状态发生变化
当 @Composable
函数直接或间接依赖的可变状态(如 mutableStateOf
、StateFlow
、LiveData
等)发生更新时,Compose 会触发该组件的重组。
示例:
1 |
|
当 count.value
变化时,Text
组件会重新执行(重组)以展示最新值。
父组件重组且传入的参数发生变化
如果父组件发生重组,且传递给子组件的参数值与上次不同,则子组件会触发重组。反之,若参数未变化,子组件会被跳过(智能重组)。
示例:
1 |
|
当 count
变化导致父组件重组时,若 text
参数值改变,Child
会重组;若 text
不变(如参数是固定值),则 Child
不会重组。
组件被 key
标记且 key
值变化
使用 key
函数可以强制指定组件的标识。当 key
值变化时,即使参数未变,组件也会重新创建(而非复用),触发重组。
示例:
1 | LazyColumn { |
总结
Compose 的重组核心原则是“只重组依赖变化状态的组件”,通过这种精细化的更新机制,避免了不必要的渲染开销,提升了性能。开发者无需手动触发刷新,只需关注状态管理,Compose 会自动处理重组逻辑。
变化的场景
ViewModel中
若组件依赖 ViewModel
中的状态(如 StateFlow
暴露的数据),当数据更新并通过 collectAsState()
等方法被组件观察到时,会触发重组。
示例:
1 |
|
Effect中
通过 LaunchedEffect
、DisposableEffect
等副作用 API 改变状态时,若组件依赖该状态,也会触发重组。
示例:
1 |
|
没有触发重组解决
可变状态属性发生变化是不会重组的。
我们可以使用copy触发重组
1 | currQues.value = currQues.value?.copy(isCorrect = isCorrect) |
但是注意下面的写法不会触发重组
1 | currQues.value?.isCorrect = isCorrect |
所以注意
需要属性修改的时候重组,就
不能提前先赋值
,赋值后就算copy了,也不会重组。