molikto
04/01/2020, 3:03 AMZach Klippenstein (he/him) [MOD]
04/01/2020, 1:36 PMonActive instead of remember, so you don’t need to store your subscription in your state.
2. Annotate your state with @Model, which will automatically wire up recomposition so you don’t need Recompose or current.composing.
You probably also want to key the subscription on the observable itself, so if the caller starts passing in a different observable, you update the subscription.
@Model private class State(
var set: Boolean = false,
var value: Any? = null
)
@Composable fun <T> Observe(
@Pivotal observable: Observable<T>,
children: @Composable() (T) -> Unit
) {
val current by remember { State() }
onActive {
val subscription = observable.subscribe {
current.set = true
current.value = it
}
onDispose { subscription.dispose() }
}
@Suppress("UNCHECKED_CAST")
if (current.set) {
children(current.value as T)
}
}
@Pivotal ensures that, if the caller starts passing in a different observable, your entire Observe composable is removed from the composition and recreated (including current and the subscription), which means that children will temporarily stop getting called until the first value is received from the new observable. If you want to hang onto the last value until the new observable emits, remove the @Pivotal annotation and change onActive to onCommit(observable), which will keep your state around but just tear down and recreate the subscription.molikto
04/01/2020, 4:10 PMsource.map{} or source.distinctUntilChanged() so they don't have a meaningful equals? I do encountered a lot of time the Observable body needs to be forcely recomposed entirely, these cases I have a key(..) outside where I manually select a proper keymolikto
04/01/2020, 4:18 PMonActive will cause the observable body always miss the first frame. If the observable is a ReplaySubject or a BehaviourSubject currently having a value, then my code will compose the children during the first frameLeland Richardson [G]
04/03/2020, 3:08 PMZach Klippenstein (he/him) [MOD]
04/03/2020, 5:56 PMmolikto
04/24/2020, 6:04 AMState<T> is returned. Although in case of Observable you need to provide a default value. I found this works better than what I have before, 1. less indentation... 2. I actually needs to provide an meaningful default value most of time. 2. it is convenient to work with multiple observables compared to combineLatest