本文介绍了如何在Composable函数中正确创建一个ViewModel对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的MainActivity中有此结构:
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = ItemsScreen.route
) {
composable(
route = ItemsScreen.route
) {
ItemsScreen(
navController = navController
)
}
composable(
route = ItemDetailsScreen.route + "/{itemId}",
arguments = mutableStateListOf(
navArgument("itemId") {
type = NavType.StringType
}
)
) { backStackEntry ->
val itemId = backStackEntry.arguments?.getString("itemId") ?: ""
ItemDetailsScreen(
navController = navController,
itemId = itemId
)
}
}
在ItemDetailsScreen a LazyColumn:
LazyColumn {
items(
items = itemsResponse.data
) { item ->
ItemCard(
item = item,
onItemClick = {
navController.navigate(ItemDetailsScreen.route + "/${item.id}")
}
)
}
}
然后单击ItemDetailsScreen导航到ItemDetailsScreen:
fun ItemDetailsScreen(
navController: NavController,
itemId: String,
viewModel: ItemDetailsViewModel = hiltViewModel()
) {
Log.d(TAG, itemId)
}
如图所示,在构造函数中创建了ViewModel对象。当我打开ItemDetailsScreen时,LOG语句被触发两次。如果我注释此行://viewModel: ItemDetailsViewModel = hiltViewModel()
LOG语句按预期工作,它只打印一次ItemID。如何使用ViewModel对象使其只能触发一次LOG语句?
以下也是ViewModel类:
@HiltViewModel
class ItemDetailsViewModel @Inject constructor(
private val useCases: UseCases
): ViewModel() {
private val _itemState = mutableStateOf<Response<Item>>(Success(Item()))
val itemState: State<Response<Item>> = _itemState
fun getItem(id: String) {
viewModelScope.launch {
useCases.getItem(id).collect { response ->
_itemState.value = response
}
}
}
}
推荐答案
您不必担心日志语句被打印两次。ViewModel创建代码没有任何错误。LOG语句被打印两次,因为它直接位于可组合函数中,而可组合函数会重新组合很多内容(有时甚至以一种不可预测的方式)。如果只想在首次合成Composable时执行某些操作,请将其放入LaunchedEffect
块中。查看documentation以了解有关这些效果处理程序的更多信息。
这篇关于如何在Composable函数中正确创建一个ViewModel对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!