Ive been doing `LaunchedEffect(list.size){ scrollT...
# compose
z
Ive been doing
LaunchedEffect(list.size){ scrollToTop() }
in order to scroll my
LazyColumn
to the top whenever the list size changes. This works great, but it also scrolls the list to the top whenever I navigate back to it since the LaunchedEffect is restarted. I could work around this with
rememberSaveable
, but that doesnt seem ideal. Is there another better approach?
a
Does the
list
instance change? If it doesn't change, you can use something like:
Copy code
LaunchedEffect(list) {
    snapshotFlow { list.size }.drop(1).collect {
        scrollToTop()
    }
}
z
@Albert Chang I think the entire
LaunchedEffect
starts anew everytime the screen re-enters the composition (e.g. when navigating back to it).
a
That's why I'm using
drop(1)
.
z
Ooooooh. Hmm, let me play around with it a bit! In the meantime, heres what I put together to solve it as well (your solution looks way better though).
Copy code
@Composable
inline fun <T : Any> RememberEffect(
    value: T,
    crossinline action: suspend () -> Unit,
) {
    val scope = rememberCoroutineScope()

    rememberSaveable(value) {
        value.also {
            scope.launch { action() }
        }
    }
}
Yeah, that works too! 👍🏽 Im pretty sure its the better approach out of the two as well, theres really no need to save any values outside the composition!
Awesome, I really appreciate the help, thank you! 🙏🏽 Since Ill be using this in quite a few spots I put this together:
Copy code
@Composable
fun <T> ScrollToTop(
    controller: ListController,
    key: T,
) {
    val updatedKey by rememberUpdatedState(key)

    LaunchedEffect(Unit) {
        snapshotFlow { updatedKey }
            .drop(1)
            .collect {
                controller.scrollToTop(
                    animated = true,
                )
            }
    }
}
138 Views