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

bnvinay92

10/07/2023, 12:28 PM
When does a remember() function's lambda get called again? I have:
Copy code
ParentComposable {
  ChildComposable {
     remember("constant") { someConstructor() }
  }
}
My assumption is that
someConstructor
will only get called once but it seems whenever the ParentComposable recomposes the constructor gets called again. Is this how compose works or am i missing something else that's causing the remember to run again?
v

vide

10/07/2023, 12:56 PM
are you sure your constant doesn't change?
another possibility could be that the remember call is removed from the composition and added back later?
a

ascii

10/07/2023, 2:37 PM
If a composable leaves composition, then of course stuff like remember and effect(Unit) will "re-execute" when the particular composable comes back. If compose would store snapshots for everything forever, things would quickly go out of hand.
If you want one-off code to truly run only once regardless of leaving composition, you'll have to use some external controls, e.g. an atomic or volatile boolean flag that you'd check (and set) inside the block. Or in your constructor example, store it yourself in a var outside of compose.
a

Adib Faramarzi

10/07/2023, 3:02 PM
It will get called one every composition and not every recomposition. So if your composable is kept in the composition and is recomposing (due to changes, animations, etc...), since the key that you provided has not changed,
someConstructor
will not get called. But if it goes away from composition and is brought back, it will be called again.
b

bnvinay92

10/07/2023, 4:43 PM
Thanks for the direction
Any techniques to debug when a composable leaves a composition?
Nvm, found it: DisposableEffect(Unit) { // Log when disposed (removed) onDispose { Log.d("MyComposable", "Disposed (Removed)") } }
So what was happening was that my ChildComposable was actually:
Copy code
ParentComposable {
   when {
     case 1 -> ChildComposable
     case 2 -> ChildComposable
   }    
}
It looks like the compose compiler generates different uids for each one so my case statements were removing and adding these from the composition instead of recomposing it.
z

Zach Klippenstein (he/him) [MOD]

10/08/2023, 2:30 AM
Yep, that’s the “positional” part of positional memoization
a

ascii

10/08/2023, 3:44 AM
I think this is where
key()
could be useful; if it's the same composable fn and you don't want one to be removed and the other added.
a

Adib Faramarzi

10/08/2023, 6:49 AM
Yes. This is explained as an example for a
for
code in the Android docs for Compose (in which they use a
key(item.id)
in the
for
block to know which item is which.