繁体   English   中英

为什么当 state 在视图 model 中更改时,路由的 Composable 会重新组合?

[英]Why does the Composable for the route recompose when state changes in the view model?

TLDR:问题是,当composable不依赖于在我的 ViewModel 中更新的值时,为什么我会在 logcat 中同时看到“路由可组合”和“主屏幕”? 我希望只看到“主屏幕”,因为这是唯一使用 ViewModel 中的 state 值的组合。

我最近在生产应用程序中遇到了一种情况,其中我的可组合路由被调用了两次,导致 UI 出现轻微闪烁。 在深入研究了几个小时后,我发现闪烁的原因是在将 ViewModel 提供给我的撰写屏幕的路线中使用了hiltViewModel 我进一步挖掘发现,只要 ViewModel 中发生 state 更改,Route 的可组合项就会被重新组合。 我会认为只有可组合的子组件会重新组合,因为它是唯一使用 state 值的子组件?

完整的项目在这里,但基本的 Compose 代码如下所示。 (我尽可能多地删除样板)

@Composable
fun AppNav() {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Screen.Home.route) {
        addHome()
    }
}

private fun NavGraphBuilder.addHome() {
    composable(Screen.Home.route) {
        Log.i("Home", "Route Composable")
        val homeViewModel = hiltViewModel<HomeViewModel>()
        HomeScreen(
            homeCount = homeViewModel.homeCount,
            updateCount = { homeViewModel.updateCount() },
        )
    }
}

@Composable
fun HomeScreen(
    homeCount: Int,
    updateCount: () -> Unit,
) {
    Log.i("Home", "Home Screen")
    Column(modifier = Modifier.fillMaxSize()) {
        Spacer(modifier = Modifier.height(25.dp))
        Button(onClick = { updateCount() }) {
            Text("Increment count")
        }
        Spacer(modifier = Modifier.height(25.dp))
        Text("Count is: $homeCount")
    }
}

我想您需要查看在导航到不同路线时如何使用saveStaterestoreState 这是一篇关于这件事的文章: https://developer.android.com/jetpack/compose/navigation#bottom-nav

在仔细阅读文档并在Slack Channel中确认后,我发现核心问题是对 State 如何与 Compose 一起使用的误解。 我以为它只改变了 State 被消耗的可组合,而实际上任何包含(读取)State 的可组合将在 Z46A2A41CC6E552044816A2D04634 更改时重新组合。 我的示例中的代码与执行以下操作基本相同:

composable(Screen.Home.route) {
    Log.i("Home", "Route Composable")
    var homeCount by remember { mutableStateOf(0) }
    HomeScreen(
        homeCount = homeCount,
        updateCount = { homeCount++ },
    )
}

如果 State 像此版本一样在 Composable 中直接更新,或者 State 像原始代码一样在 ViewModel 中更新,则没有区别。 无论哪种方式,包含 State 的 Composable 都会重新组合。

任何时候更新 state 都会发生重组。

对 value 的任何更改都将安排读取 value 的任何可组合函数的重组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM