Danylo Didkovskyi
09/18/2024, 3:07 PMSomeState
) that needs to be explicitly closed (SomeState.close()
) to be cleaned up when it is no longer in use. To simplify the creation of the state object for users, I implemented a rememberSomeState
function, which not only creates and remembers the state but also handles the resource cleanup by adding a DisposableEffect
to close the state when rememberSomeState
leaves the composition:
@Composable
fun rememberSomeState(value: SomeValue): SomeState {
val state = remember(value) {
SomeState(value)
}
DisposableEffect(value) {
onDispose {
state.close()
}
}
return state
}
My question is: How natural would this approach be in the Compose world?
I’ve typically seen rememberSomething
functions used for managing state that doesn’t need explicit resource management (e.g., objects that don’t require closing or cleanup). I’m wondering if embedding DisposableEffect
within a rememberSomething
function is an accepted pattern, or if it's better to leave the cleanup responsibility to the caller of the composable.
Any insights or guidance would be greatly appreciated.Zach Klippenstein (he/him) [MOD]
09/18/2024, 5:24 PMDisposableEffect
could be state
instead of value
, which is technically more precise since it's state
that's captured by the effect but what you're doing should have the same effect since the same key is used for remembering the state anyway.Halil Ozercan
09/18/2024, 5:33 PMZach Klippenstein (he/him) [MOD]
09/18/2024, 5:35 PMRememberObserver
, since it can be remembered by code outside your control. If you have a private object that you're remembering and returning a different object, then it is ok.
E.g. In the OP snippet, making SomeState
implement RememberObserver
would be bad. But if it returned state.actualState
and actualState
didn't implement RO, that would be ok.Danylo Didkovskyi
09/18/2024, 9:55 PMAlex Vanyo
09/25/2024, 1:45 AMRememberObserver
being remembered by something else, you could do:
@Composable
fun rememberSomeState(value: SomeValue): SomeState =
remember(value) {
object : RememberObserver {
val state = SomeState(value)
override fun onAbandoned() = onForgotten()
override fun onForgotten() {
state.close()
}
override fun onRemembered() = Unit
}
}.state