https://kotlinlang.org logo
#compose
Title
# compose
p

Pablo

02/26/2024, 2:06 PM
Is there any problem with this sample?
var currentDessertImageId by rememberSaveable *{*
_mutableStateOf_(desserts[uiState.value.currentDessertIndex].imageId)
}
Something is not working because each recomposition,
currentDessertImageId
is not changing... is always the same, and that is not normal because each recomposition
currentDessertIndex
is different, and
desserts[uiState.value.currentDessertIndex].imageId
is different too, I checked it with a Log. This is the Log:
Copy code
2024-02-26 15:11:21.014  6790-6790  XXXX com.example.dessertclicker D  currentDessertIndex: 0 + desserts[uiState.value.currentDessertIndex].imageId: 2130968578 + currentDessertImageId: 2130968578
2024-02-26 15:11:23.098  6790-6790  XXXX com.example.dessertclicker D  currentDessertIndex: 1 + desserts[uiState.value.currentDessertIndex].imageId: 2130968579 + currentDessertImageId: 2130968578
2024-02-26 15:11:23.248  6790-6790  XXXX com.example.dessertclicker D  currentDessertIndex: 2 + desserts[uiState.value.currentDessertIndex].imageId: 2130968580 + currentDessertImageId: 2130968578
c

Chrimaeon

02/26/2024, 2:11 PM
you’ll need to pass the
currentDessertIndex
as an input parameter to
remeberSavable
otherwise, as the name suggests, its “remembered”.
p

Pablo

02/26/2024, 2:14 PM
@Chrimaeon can you explain it please? I don't know why passing
currentDessertIndex
should behave different than passing
imageId
both are integer values
and both are changing each recomposition
c

Chrimaeon

02/26/2024, 2:17 PM
Copy code
val currentIndex = uiState.value.currentDessertIndex
    var currentDessertImageId by rememberSaveable(currentIndex) {
        mutableStateOf(desserts[currentIndex].imageId)
    }
without the “input” parameter the `remember`’s closure is only called once with the first value.
remeberX
does not know that you “input” has changed and need to re-evaluate.
👆 1
also if
desserts
change over time, you’ll need to pass that as well.
remember
stores the value until it leaves the Composition. However, there is a way to invalidate the cached value. The
remember
API also takes a
key
or
keys
parameter. If any of these keys change, the next time the function recomposes,
remember
invalidates the cache and executes the calculation lambda block again. This mechanism gives you control over the lifetime of an object in the Composition. The calculation remains valid until the inputs change, instead of until the remembered value leaves the Composition.
p

Pablo

02/26/2024, 2:24 PM
oh, I see, now I know where is the problem, I was killing flies with cannon shots 😄
I can solve the isssue simply not using the remember, and just doing this:
val currentDessertImageId = desserts[uiState.value.currentDessertIndex].imageId
I'm migrating a sample project to viewmodel and this is a huge mistake from me
I noticed it thanks to you
I don't need to remember a value that is changing in each recomposition!
now those values are stored in a viewmodel, inside that UiState class
now all it's clear, thanks
my brain is still changing to using declarative uis, states, etc..