返回导航后如何保留状态?ViewModel提升后展开状态丢失
问题描述
我有一个列表页面,点击列表项会跳转到评论页面,通过该列表项的permalink获取评论数据。返回后再次点击同一列表项时,页面状态会被清空,需要重新获取数据——我希望在permalink未变化时避免重复请求。
我尝试将CommentsViewModel提升到NavHost外部并传入评论页面,这确实阻止了重复获取数据,能正常显示评论和原帖数据,但所有评论的展开状态丢失了。更奇怪的是,调试时发现uiState中的comments、expandedComments、originalPost和permalink字段均为空,但模拟器里却能正常显示评论,我对此感到困惑,寻求解决方案。
相关代码
NavHost 代码
NavHost(navController = navController, startDestination = NavRoutes.AUTH.name) { fun navToComments(url: String, permalink: String) { navController.navigate("${NavRoutes.COMMENTS.name}?url=$url&permalink=$permalink") } composable( route = "${NavRoutes.COMMENTS.name}?url={url}&permalink={permalink}", arguments = listOf(navArgument("url") { type = NavType.StringType }, navArgument("permalink") { type = NavType.StringType }) ) { navBackStackEntry -> val url = navBackStackEntry.arguments?.getString("url") val permalink = navBackStackEntry.arguments?.getString("permalink") CommentsScreen(url ?: "", permalink ?: "") } ... }
CommentsViewModel 代码
@HiltViewModel class CommentsViewModel @Inject constructor( private val authRepository: RedditAuthRepositoryImp, ) : ViewModel() { private val _uiState = MutableStateFlow( CommentsUiState( comments = listOf<CommentModel>(), expandedComments = setOf<String>(), originalPost = null, permalink = "" ) ) val uiState = _uiState.asStateFlow() fun updatePermalink(permalink: String) { _uiState.update { currentState -> currentState.copy(permalink = permalink) } } fun getComments(url: String) { viewModelScope.launch { val commentsResponse: List<CommentsModel> = authRepository.getComments(url) val originalPost: CommentModel = commentsResponse[0].data.children[0] val comments: List<CommentModel> = (commentsResponse[1].data.children) val expandedComments = getFlattenedComments(comments) _uiState.update { currentState -> currentState.copy( expandedComments = expandedComments, comments = comments, originalPost = originalPost ) } } } fun isExpanded(commentNode: CommentModel): Boolean { return _uiState.value.expandedComments.contains(commentNode.data.id) } ... }
CommentsScreen 代码
@Composable fun CommentsScreen( url: String, permalink: String, modifier: Modifier = Modifier ) { val viewModel: CommentsViewModel = hiltViewModel() val commentsUiState = viewModel.uiState.collectAsState() val originalPostData = commentsUiState.value.originalPost?.data LaunchedEffect(Unit) { if (commentsUiState.value.permalink != permalink) { viewModel.getComments("$OAUTH_BASE_URL$permalink.json") viewModel.updatePermalink(permalink) } } ... }
内容的提问来源于stack exchange,提问作者cyancore
相关产品推荐
相关产品推荐

