collectAsState获取旧响应引发导航逻辑异常的问题解决咨询
问题根源
你遇到的问题核心是StateFlow中留存了旧的API响应数据:第一次请求后authUserData持有了“已注册”的结果,当用户返回发起新请求时,UI先读取到旧数据,触发了错误的登录页面导航;直到第二次API请求完成,新数据才覆盖旧值,但此时导航逻辑已经执行过了。
解决方案
1. 在发起API请求前重置StateFlow状态
修改UserAuthViewModel,自己维护一个可变的StateFlow,每次请求前将状态置为null,确保UI不会读取到旧数据:
class UserAuthViewModel @Inject constructor(private val repository: Repository) : ViewModel() { // 内部维护可变StateFlow,初始值为null private val _authUserData = MutableStateFlow<AuthResponseModel?>(null) // 对外暴露不可变的StateFlow val authUserData: StateFlow<AuthResponseModel?> = _authUserData.asStateFlow() fun getAuthUserData(textUser: String, countryCode: String) { viewModelScope.launch { // 请求前重置状态,清空旧数据 _authUserData.value = null val result = repository.getAuthUserData(AuthUser(username = textUser, country_dial_code = countryCode)) // 将新结果更新到StateFlow _authUserData.value = result } } fun getAuthUserDataEmail(textUser: String) { viewModelScope.launch { // 请求前重置状态 _authUserData.value = null val result = repository.getAuthUserData(AuthUser(username = textUser)) Log.d("TAG", "getAuthUserDataEmail: ${result?.result?.user_exist}") // 更新为最新结果 _authUserData.value = result } } }
2. 优化导航触发逻辑
调整LaunchedEffect的依赖条件,确保只有当新的API响应(userData从null变为非null)且navigation为true时,才执行导航:
LaunchedEffect(userData) { if (userData != null && navigation) { when (userData?.result?.user_exist) { "USER_NOT_EXISTS" -> navController.navigate(NavScreens.REGISTRATION.route) "ACCOUNT_EXISTS" -> navController.navigate(NavScreens.LOGIN.route) "ACCOUNT_NOT_VERIFIED" -> { sharedViewModel.addOtpType("account_verification") navController.navigate(NavScreens.VERIFY_ACCOUNT.route) } else -> Toast.makeText(context, "${userData?.message}", Toast.LENGTH_SHORT).show() } loading = false navigation = false } }
3. 清理无用代码
点击事件中的userData行没有实际作用,直接删除:
} else { if (textUser.contains("@")) { // for email sharedViewModel.addType(false) sharedViewModel.addUsername(textUser) navigation = true authViewModel.getAuthUserDataEmail(textUser = textUser) loading = true // 删掉这行无用代码:userData } else {
补充说明
如果你的Repository内部对authUserData有缓存逻辑,需要确保每次调用getAuthUserData时都发起新的网络请求,而不是返回缓存的旧数据,否则即使ViewModel重置状态,新请求可能还是拿到旧结果。
内容的提问来源于stack exchange,提问作者Priyanshu Raj
相关产品推荐
相关产品推荐

