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

返回导航后如何保留状态?ViewModel提升后展开状态丢失

问题描述

我有一个列表页面,点击列表项会跳转到评论页面,通过该列表项的permalink获取评论数据。返回后再次点击同一列表项时,页面状态会被清空,需要重新获取数据——我希望在permalink未变化时避免重复请求。

我尝试将CommentsViewModel提升到NavHost外部并传入评论页面,这确实阻止了重复获取数据,能正常显示评论和原帖数据,但所有评论的展开状态丢失了。更奇怪的是,调试时发现uiState中的comments、expandedComments、originalPost和permalink字段均为空,但模拟器里却能正常显示评论,我对此感到困惑,寻求解决方案。


相关代码
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:23:09