https://kotlinlang.org logo
h

Halil Ozercan

09/02/2020, 8:13 PM
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

Ian Lake

09/02/2020, 9:42 PM
This is a known issue. See the feature request https://issuetracker.google.com/issues/165642391
t

Timo Drick

09/02/2020, 10:50 PM
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

Sean McQuillan [G]

09/02/2020, 10:52 PM
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

Timo Drick

09/02/2020, 10:52 PM
Maybe just create an instance of your ViewModel without using this special viewModel<...>() system
s

Sean McQuillan [G]

09/02/2020, 10:52 PM
Any object that implements that will call
onEnter
and
onLeave
when it's remembered (or forgotten) by composition
t

Timo Drick

09/02/2020, 10:54 PM
Maybe also viewModel is not what you want. Just use a normal class
i

Ian Lake

09/02/2020, 11:16 PM
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

Timo Drick

09/03/2020, 12:00 AM
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

Ian Lake

09/03/2020, 12:39 AM
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

Halil Ozercan

09/03/2020, 6:39 AM
As this is just an experiment, it's best to wait for the fix to land
Thanks everyone 👍
3 Views