Is there a way to access the `remember`ed value fr...
# compose
u
Is there a way to access the `remember`ed value from the prior composition when re-calculating a new value upon recomposition? I see that the internal implementation of
remember
has access to the prior value, but does not expose it. Is there an API that does? This can be done via an effect, but this implies an additional recomposition to use the new value. I need this for updating a list that blends old values with new values from changed inputs. Right now I'm working around the issue with a second `remember`ed
MutableState
that is updated to the prior value on every recomposition. Seems ridiculously complicated when
remember
already has the info, just won't make it available. This is what I want, conceptually; I am aware that the API would have to look a little different to accommodate initial calculation:
val list = remember(modelData) { priorValue -> mergeUpdatedList(priorValue, modelData) }
z
Trying to do this is typically a code smell. • Why are you merging lists in your view layer, instead of your presentation/ViewModel layer or above? • Composition isn’t guaranteed to see intermediate values if states are changed very quickly, which means for this sort of thing your code might not see all the values you expect.
u
@Zach Klippenstein (he/him) [MOD] This is for integrating a legacy component (GoogleMap Marker) into Compose. The Marker owns the data (Marker position) after initialization. (Technically I am integrating with android-maps-compose MarkerState, it carries forward the Marker's ownership model.) So there are 2 competing sources of truth here that I am merging in the list: initial source of truth is the app's data model, afterwards the source of truth is the Marker. There are a bunch of Markers, which I need to organize in a list-like structure that is needed as an input by another legacy component. This question is not about states, it is related to slots. A slot has a well-defined prior value from the preceding composition, after the initial composition.
What I need boils down to this modified Composer.cache() implementation. It uses
@ComposeCompilerApi
calls, and the original
Composer.cache()
is
@ComposeCompilerApi
as well. What are the implications of redefining and leveraging
@ComposeCompilerApi
functions in app code?
Copy code
inline fun <T> Composer.cache(
    invalid: Boolean,
    initial: @DisallowComposableCalls () -> T,
    block: @DisallowComposableCalls (T) -> T
): T {
    @Suppress("UNCHECKED_CAST")
    return rememberedValue().let {
        if (it === Composer.Empty) {
            val value = initial()
            updateRememberedValue(value)
            value
        } else if (invalid) {
            val value = block(it as T)
            updateRememberedValue(value)
            value
        } else it as T
    }
}