[英]Jetpack compose data store keeps recomposing screen
我正在使用 jetpack compose 从共享偏好迁移到数据存储。 一切正常(数据已保存并可成功撤回)。 但是,每当检索到数据时,可组合项就会不断地重新组合。 我正在使用 MVVM 架构,下面是我实现数据存储的方式。
下面在我的 AppModule.kt 中声明
SingletonComponent 中的应用模块
@Provides
@Singleton
fun provideUserPreferenceRepository(@ApplicationContext context: Context):
UserPreferencesRepository = UserPreferencesRepositoryImpl(context)
然后这是我的 ViewModel:
@HiltViewModel
class StoredUserViewModel @Inject constructor(
private val _getUserDataUseCase: GetUserDataUseCase
): ViewModel() {
private val _state = mutableStateOf(UserState())
val state: State<UserState> = _state
fun getUser(){
_getUserDataUseCase().onEach { result ->
val name = result.name
val token = result.api_token
val balance = result.balance
val agentCode = result.agent_code
_state.value = UserState(user = UserPreferences(name, agentCode, token, balance))
}.launchIn(viewModelScope)
}}
最后,这是我的存储库实现:
class UserPreferencesRepositoryImpl @Inject constructor(
private val context: Context
): UserPreferencesRepository {
private val Context.dataStore by preferencesDataStore(name = "user_preferences")
}
private object Keys {
val fullName = stringPreferencesKey("full_name")
val api_token = stringPreferencesKey("api_token")
val balance = intPreferencesKey("balance")
val agentCode = intPreferencesKey("agent_code")
}
private inline val Preferences.fullName get() = this[Keys.fullName] ?: ""
private inline val Preferences.apiToken get() = this[Keys.api_token] ?: ""
private inline val Preferences.balance get() = this[Keys.balance] ?: 0
private inline val Preferences.agentCode get() = this[Keys.agentCode] ?: 0
override val userPreferences: Flow<UserPreferences> = context.dataStore.data.catch{
// throws an IOException when an error is encountered when reading data
if (it is IOException) {
emit(emptyPreferences())
} else {
throw it
}
}.map { preferences ->
UserPreferences(name = preferences.fullName, agent_code = preferences.agentCode, api_token = preferences.apiToken,
balance = preferences.balance)
}.distinctUntilChanged()
我不知道是什么导致可组合重组。 以下是可组合的:
@Composable
fun LoginScreen(
navController: NavController,
userViewModel: StoredUserViewModel = hiltViewModel()
) {
Log.v("LOGIN_SCREEN", "CALLED!")
userViewModel.getUser()
}
如果有人能告诉我哪里做错了,请赐教。 我试图在 AppModule 中更改 UserPreferencesRepository 的实现,但没有运气。
下面是 UseState.kt,它只是一个数据 class
data class UserState(
val user: UserPreferences? = null
)
下面是 UserPreferences.kt
data class UserPreferences(val name: String, val agent_code: Int, val api_token: String, val balance: Int)
这是预期的行为:您在每次重组时都调用getUser
。
@Composable
function 是一个视图构建器,应该没有副作用。
相反,您可以使用特殊的副作用 function,例如LaunchedEffect
,它只会启动一次作业,直到它从视图树中删除或更改key
参数:
LaunchedEffect(Unit) {
userViewModel.getUser()
}
但这也将在配置更改的情况下被重新调用,例如屏幕旋转。 为了防止这种情况,您有两种选择:
init
中调用getUser
:在这种情况下,它保证只调用一次。文档中有关撰写副作用的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.