为什么 LaunchedEffect(true) 可疑?

Nav*_*eed 5 android android-jetpack-compose

我正在努力使用 compose 来实现 MVI。为了让我遵循正确的事件循环,我需要通过我的视图模型传播点击事件,然后观察副作用。我研究了一些实现,它们都用于LaunchedEffect(true)观察副作用并采取行动。

我有一个类似的设置,例如:

@Composable
fun HelloComposeScreen(
    viewModel: MyViewModel = hiltViewModel(),
    onClickedNext: () -> Unit
) {
    LaunchedEffect(true) {
        viewModel.sideEffect.collectLatest { sideEffect ->
            when (sideEffect) {
                DashboardSideEffect.CreateParty -> onClickedNext()
            }
        }
    }
    Button(
        onClick = { viewModel.onEvent(UserEvent.ClickedButton)},
    ) {
        Text("Click Me")
    }
}
Run Code Online (Sandbox Code Playgroud)

这导致我使用LaunchedEffect(true)任何具有导航或一次性事件的屏幕,但官方文档有此警告

警告:LaunchedEffect(true) 与 while(true) 一样可疑。尽管它有有效的用例,但请始终停下来并确保这就是您所需要的。

我的问题是:

  • 具体什么时候取消LaunchedEffect?文档说它与调用站点的生命周期相匹配。这是本例中的组成吗?
  • 考虑到官方文档有警告吗?我不应该使用此LaunchedEffect(true)设置来观察我的项目的副作用吗?有什么替代方案吗?

Phi*_*hov 10

LaunchedEffect与它的协程一起被取消,有两种变体:

  1. 传递的key参数被更改 - 在这种情况下,当前的参数LaunchedEffect将被取消并创建一个新的参数。
  2. LaunchedEffect例如,如果您将其(或其任何级别的父级)放入块中if并且条件变为 ,则从生命树中删除false

如果不需要传递任何key应该重新启动的内容LaunchedEffect,则可以传递Unit。任何其他常量(例如true您的情况)都被认为是可疑的,因为它无法在运行时更改,但对于任何编码器来说可能看起来都像复杂的逻辑。

  • LaunchedEffect(true) 和 LaunchedEffect(Unit) 具有相同的行为。Android 文档:要创建与调用站点的生命周期相匹配的效果,需要将像 Unit 或 true 这样的不变常量作为参数传递。 (5认同)