Recomposer.applyAndCheck
java.lang.IllegalStateException — неподдерживаемое одновременное изменение во время композиции. Объект состояния был изменен в результате композиции, а также изменен вне композиции.
Время от времени у меня возникает ошибка с неподдерживаемым одновременным изменением.
Я пытаюсь понять источник проблемы. Когда я изучал компоновку, я использовал coroutineScope с Dispatchers.IO для обновления состояния, и это вызывало ту же проблему. Я прочитал https://developer.android.com/develop/u ... de-effects и не вижу никаких проблем в своем коде.
Что это за проблема? ?
Может быть, во время изменений состояния мне следует использовать viewModelScope?
Код: Выделить всё
is HomeEvent.OnFreeCouponDeclined -> {
homeState.update {
copy(isDeclined = false)
}
}
Код: Выделить всё
is HomeEvent.OnFreeCouponDeclined -> {
viewModelScope.launch {
homeState.update {
copy(isDeclined = false)
}
}
}
Код: Выделить всё
private fun observeInventory() {
viewModelScope.launch {
(Dispatchers.Default) {
getInventoryInteractor.invoke().collectLatest {
(Dispatchers.Main) {
homeState.value = homeState.value.copy(categories = it.map {
it.copy(subCategories = emptyList())
})
}
}
}
}
}
Пожалуйста, прошу у вас совета, на что мне следует обратить внимание?
Может быть, этот код?
Код: Выделить всё
LaunchedEffect("${state.currentPage}_${sliderHoldTimestamp}_${sliderItems.size}") {
delay(AUTO_SLIDER_DELAY)
coroutineScope.launch {
if (sliderItems.isNotEmpty() && state.pageCount != 0) {
var newPosition = state.currentPage + 1
if (newPosition > sliderItems.size - 1) newPosition = 0
state.animateScrollToPage(newPosition.mod(state.pageCount))
}
}
}
Код: Выделить всё
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
const val foundation = "androidx.compose.foundation:foundation:1.6.1"
Код: Выделить всё
private var _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(4000L),
initialValue = HomeState(isAddressAddedFromOnboarding)
)
private fun checkIsActiveOrder() {
viewModelScope.launch {
isActiveOrderInDeliveryInteractor.invoke().collectLatest {
_homeState.value = _homeState.value.copy(isActiveOrder = it)
}
}
}
Or with val _homeState
_homeState.update {
copy(isNotificationPermissionAsked = it)
}
Я использую расширение:
Код: Выделить всё
infix fun MutableStateFlow.update(updater: T.() -> T) {
this.value = updater(this.value)
}
Код: Выделить всё
[...]
: ViewModel() {
private val _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState.asStateFlow()
init {
viewModelScope.launch {
combine(
getAccountTypeInteractor.invoke(),
getDeliveryEstimatedTimeInteractor.invoke(),
getInventoryInteractor.invoke(),
getSliderItemsInteractor.invoke(),
getBestSellersProductsInteractor.invoke(),
getSpecialCategoriesInteractor.invoke(),
getCurrentAddressInteractor.invoke(),
getVerificationAgeStateInteractor.invoke(),
getIsNewDarkStoreSyncInteractor.invoke(),
getAdditionalMenuOptionsInteractor.invoke(),
getBasketTotalValueWithoutDiscountInteractor.invoke(),
checkIsStoriesDataLoadedInteractor()
) { accountType, deliveryEstimatedTime, inventory, sliders, bestSellers, specialCategories, currentAddress, ageVerificationState, isLoading, additionalMenuOptions, basketTotalValueWithoutDiscount, storiesDataLoaded, ->
// it doesn't log anything, not even null
Log.d("homeStateVALUES", """
accountType: $accountType,
deliveryEstimatedTime: $deliveryEstimatedTime,
inventory: $inventory,
sliders: $sliders,
bestSellers: $bestSellers,
specialCategories: $specialCategories,
currentAddress: $currentAddress,
ageVerificationState: $ageVerificationState,
isLoading: $isLoading,
additionalMenuOptions: $additionalMenuOptions,
basketTotalValueWithoutDiscount: $basketTotalValueWithoutDiscount,
storiesDataLoaded: $storiesDataLoaded
""")
HomeState(
isAddressAddedFromOnboarding = isAddressAddedFromOnboarding,
isLogged = accountType == AccountType.STANDARD_ACCOUNT,
chipTime = deliveryEstimatedTime,
categories = inventory.map {
it.copy(subCategories = emptyList())
},
sliderItems = sliders,
bestsellers = bestSellers,
specialCategories = specialCategories,
currentAddress = currentAddress,
ageVerificationState = ageVerificationState,
isLoading = isLoading,
additionalMenuOptions = additionalMenuOptions,
basketTotalValueWithoutDiscount = basketTotalValueWithoutDiscount,
storiesDataLoaded = storiesDataLoaded
)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(1000L),
initialValue = _homeState.value
)
}
}
onTriggeredEvent~
is HomeEvent.OnFreeCouponAccepted -> {
viewModelScope.launch {
_homeState.updateFlow {
copy(isAddressAddedFromOnboarding = false)
}
}
}
HomeScreen
fun HomeScreen(
state: StateFlow // I'm using here viewModel.homeState
) {
val homeState by state.collectAsStateWithLifecycle()
Подробнее здесь: https://stackoverflow.com/questions/785 ... omposition
Мобильная версия