https://kotlinlang.org logo
#compose-android
Title
# compose-android
a

Atul Gupta

12/06/2023, 3:38 PM
I have use-case where I want to update a value in compose based on it’s previous value something like below
Copy code
val deltaState by remoberDelta(key, valueToTrack) { oldValue -> createNewValueBasedOnPreviousValue(oldValue) }
is there some api which can achieve this is nicer syntax?
here
valueToTrack
can be some data(maybe a data class) which is passed to composable. Trailing lambda should be invoked when Compose runtime thinks that
valueToTrack
has been changed
I added smtng like below
Copy code
@Composable
fun <T> rememberRef(): MutableState<T?>
{
    return remember {
        object : MutableState<T?>
        {
            override var value: T? = null

            override fun component1(): T? = value

            override fun component2(): (T?) -> Unit = { value = it }
        }
    }
}

@Composable
fun <T> rememberPrevious(
    current: T,
    shouldUpdate: (prev: T?, curr: T) -> Boolean = { a: T?, b: T -> a != b },
): T?
{
    val ref = rememberRef<T>()

    SideEffect {
        if (shouldUpdate(ref.value, current))
        {
            ref.value = current
        }
    }

    return ref.value
}
ref: https://stackoverflow.com/questions/67801939/get-previous-value-of-state-in-composable-jetpack-compose
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 3:22 PM
Doing this via composition is usually wrong, since that code can run way more often than you expect for various reasons. It may also run less often, since it won’t run until the next frame. A slightly better way is often to use
snapshotFlow
with operators like
scan
. However, nothing can ever guarantee that either of these approaches will see every state because it’s very easy to transition to multiple intermediate states without any observer ever seeing them.
There’s no api for it because trying to do this at all is usually a code smell.
a

Atul Gupta

12/07/2023, 3:24 PM
Thanks for replying
There's no api for it because trying to do this at all is usually a code smell.
I was not aware of this.. in my usecase I want to perform some task(UI event like haptic) when new element(of specific type) gets added to a LazyList.
is there any recommendation or should I model this as state where I create a state and reset that state to null?
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 3:35 PM
To do this you would have to actually differentiate the lists, which seems like more work than necessary. It would be a lot simpler to just have whatever owns your list to trigger the haptic event explicitly when something is added to the list.
thank you color 1
a

Atul Gupta

12/07/2023, 3:40 PM
Got it.. so in my case viewModel flow holds the actual data.. so whne new item is added.. I have to inovke a flow which will be listende by UI and the preform the haptic and then reset. I think this is right
z

Zach Klippenstein (he/him) [MOD]

12/07/2023, 4:07 PM
That’s one way to do it. Or you could avoid using the view to indirectly trigger the haptic and Judy inject a haptics controller into your view model and trigger it directly.
2 Views