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

ste

04/29/2022, 11:10 AM
What's the suggested approach to handle re-launchable effects in raw compose (no viewmodels)? E.g. I'd like to create a retry button which repeats an operation (when a network request fails or whatsoever). I came to this hacky solution 🧵 (which seems to work well!), are there problems I'm unaware of?
Copy code
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@OptIn(InternalComposeApi::class)
@Composable
@NonRestartableComposable
fun relaunchableEffect(
    key1: Any?,
    block: suspend CoroutineScope.() -> Unit
): () -> Unit {
    val applyContext = currentComposer.applyCoroutineContext
    val launchedEffect = remember(key1) { LaunchedEffectImpl(applyContext, block) }
    return launchedEffect::onRemembered
}
z

Zach Klippenstein (he/him) [MOD]

05/17/2022, 11:12 PM
You probably want something more like this:
Copy code
val scope = rememberCoroutineScope()

Button(onClick = { scope.launch { someSuspendFun() } })
I would avoid thinking about this as an “effect”, since in Compose an “effect” is something that is produced by composition, and in your case it’s produced by an input event, not composition.
s

ste

05/18/2022, 10:21 AM
Thanks for the reply. Is your concern related to a naming thing? The
someSuspendFun
approach forces the programmer to handle cancellation manually, so "exploiting"
LaunchedEffect
looked like the simplest option as it works out of the box
z

Zach Klippenstein (he/him) [MOD]

05/18/2022, 2:40 PM
It's not a naming concern. Effects are products of composition which mean they require recomposition to start, whereas something responding to a button click should happen immediately, before the next frame. You can create a simple abstraction that lets you limit concurrency, by cancelling previous jobs or something else, using pure coroutines and no compose at all. However, this sort of behavior probably does not belong in your UI layer, but somewhere higher up - eg your repository should probably handle multiple concurrent requests.
8 Views