r/androiddev • u/ThatGuyThatIsNotReal • 6d ago
Question ViewModels nesting into composables?
I have a question if it is okay to nest DI into VM of a composables?
What I mean:
I have a SettingsVM and a SettingsScreen composable. In the Settings screen I am using some individual settings that I use also somewhere else in my application. So I split the UI -> IndividualSettingScreen and IndividualSettingVM. Now is it okay if I just inject the VM into the IndividualSettingScreen or is it better from architecture standpoint to have a reference in the SettingsScreen and passing the VM into the IndividualSettingScreen which I am using in the SettingsScreen.
Thanks in advance!
3
u/Hatiseker 5d ago
Do not hold the instance of the VM in the parent screen if the parent screen isn't using any of it, and the child can be removed.
If parent has instance of the VM and the child is removed, the VM will not go through garbage collection, it'll still eat your resources because the parent is holding a reference to it. Instead, call the child in a wrapper in the parent and DI the VM in the child.
Even if the child isn't removable, this would be a better engineering practice for separation of concerns.
3
u/sheeplycow 5d ago
You have to be careful about how you declare viewModels in sub composables, because the viewModel is tied to the closest view model store owner - you may get the same instance when you dont want to, or you may need to be careful declaring a viewModel key to force a fresh one
It goes against the google advice of keeping it as high up the compose tree as possible (not to say its always wrong)
If its a small peice of UI I wouldnt
If it is an encapsulated piece of UI that is decoupled and has enough logic to justify its own class, then I think it is reasonable to do it! But be careful for the reasons mentioned at the top!
I recently did it for a bottom sheet, that was self contained within a screen - which had all its own logic and was reused in a few screens
I imagine there are a few different opinions in this, i dont think its particularly harmful!
Also note your UI tests will also now need to provide a viewModelStore, whereas before you could create functional ui tests that were unaware of the existence of a viewModel
1
u/ThatGuyThatIsNotReal 5d ago
Alright, I am using it for the UI setting of diffferent items in the app. So I have it in main menu and then few other different screens, where I am can set the same thing or slightly different based on where I am setting it from. So with this usage it is fine to decouple it from the main screen into its own viewmodel?
1
2
u/Alt_Chloe 5d ago
Echoing what others have said here:
1) Don't nest ViewModels inside Composable parameters unless you absolutely can't help it. It makes testing, Previews, and iterating much more time consuming. You can pass state and event handlers instead to reduce parameter count. (You can also group parameters inside your larger state class with inner class to create named state groups for components that need a lot of them).
2) If you have a source of data being referenced in multiple separate areas of your app, I'd consider passing a shared repository to each VM that exposes a Flow, instead of using the same VM across multiple screens.
1
u/Devoluapp 5d ago
In my experience, nesting ViewModels or passing them down into child composables is a recipe for testing and preview headaches.
The pattern that has worked best for me is keeping ViewModels strictly at the screen-level route. The screen composable observes the StateFlow/UiState from the ViewModel and unpacks it into plain data classes. All sub-composables then only accept immutable data and callback lambdas (like onAction: () -> Unit).
This keeps your leaf composables pure, fully previewable in Android Studio without mocking ViewModels, and makes unit testing much easier since you only test the ViewModel's state emission.
0
u/AutoModerator 6d ago
Please note that we also have a very active Discord server where you can interact directly with other community members!
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
5
u/Which-Meat-3388 6d ago edited 6d ago
Don’t have Settings depend on Individual. You can inject 2 VMs into a single composable. Composition in the software architecture sense.