You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose未按预期触发重组:文本显示随机异常问题咨询

为什么Composable中的if语句执行结果存在随机性?

你编写的Composable函数期望3秒后隐藏文本,但实际表现不稳定,有时文本正常消失,有时持续显示。代码如下:

@Composable
fun Example() {
    val show = remember {
        mutableStateOf(true)
    }
    if (show.value) {
        Text("Showing")
    }
    LaunchedEffect(Unit) {
        delay(3000)
        show.value = false
    }
}

问题原因

核心问题出在LaunchedEffect的生命周期与Composable组合状态的交互上:

  • LaunchedEffect(Unit)会在Example首次进入组合时启动协程,3秒后将show.value设为false,触发重组隐藏文本。
  • 但如果Example在3秒内因为父组件重组、页面导航、屏幕旋转等原因被移出组合,LaunchedEffect的协程会被立即取消,show.value = false这行代码永远不会执行。
  • 当Example再次进入组合时,remember的状态会被重置(因为组合节点已销毁),show重新初始化为true,若此时协程再次被取消,文本就会持续显示。这种场景的发生具有随机性,取决于外部触发的Composable生命周期变化。

解决方案

要解决这个问题,需要确保只有当文本显示时才启动延迟隐藏的协程,并且协程的生命周期与文本的显示状态绑定。可以将LaunchedEffect移入if分支中:

@Composable
fun Example() {
    val show = remember { mutableStateOf(true) }
    if (show.value) {
        Text("Showing")
        // 仅当文本显示时启动协程,协程生命周期与Text绑定
        LaunchedEffect(Unit) {
            delay(3000)
            show.value = false
        }
    }
}

修改后的效果:

  • 只有当show.value为true时,LaunchedEffect才会被添加到组合中,启动延迟协程。
  • 3秒后show.value被设为false,触发重组,Text和LaunchedEffect都会被移出组合,协程自然结束。
  • 即使Example在3秒内被移出组合,协程会被取消,但此时文本也会随Example一起消失,不会出现“文本持续显示”的情况。

内容的提问来源于stack exchange,提问作者Thomas Cook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:40:23