In one of my composable components, I want to crea...
# compose
h
In one of my composable components, I want to create a ViewModel and use it as the state source. However, once this composable is destroyed, viewModel should also get destroyed and next time the composable is rendered, a fresh new viewModel should be created. I achieved "creating a new viewModel" by introducing a remembered, random key as follows:
Copy code
// using itemId as key would still give me the same viewModel when this composable gets recreated
val key = remember(itemId) { UUID.randomUUID().toString() }
val commentsViewModel = viewModel<CommentsViewModel>(key = key)
However, I cannot remove this particular viewModel from the store without removing other viewModels that were stored in the same place. How should I proceed with this? Is this an anti-pattern?
i
This is a known issue. See the feature request https://issuetracker.google.com/issues/165642391
t
Maybe you mix something up here. But when you use remember {} also without any key the created value is lost when the composable is disposed. You can track the lifecycle of a composable with.
onActive { log("onActive") ; onDispose { log("dispose") } }
Also if you want to do some cleanup in your ViewModel class you can trigger it from onDispose
s
Best advice – wait for the bug Ian linked to land. If you wanted to build something today, my recommendation would be to make an object that implements
CompositionLifecycleObserver
that's responsible for the cleanup code. https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLifecycleObserver.kt;l=37?q=CompositionLifecycle
t
Maybe just create an instance of your ViewModel without using this special viewModel<...>() system
s
Any object that implements that will call
onEnter
and
onLeave
when it's remembered (or forgotten) by composition
t
Maybe also viewModel is not what you want. Just use a normal class
i
You'd need to use
viewModel
if you want to have state that is retained over configuration changes (
remember
and the like do not do that)
t
You could just use
Copy code
rememberSavedInstanceState
This will maybe later also keeps it state when you are using a navigation framework and the screen is still in backstack.
i
Both
viewModel
and
rememberSavedInstanceState
would work with the upcoming Navigation framework integration
👍 1
They aren't interchangable though - what you can save in saved instance state is much, much more restrictive than what you can save in a ViewModel
h
As this is just an experiment, it's best to wait for the fix to land
Thanks everyone 👍