Search code examples
androidkotlinandroid-jetpack-composeandroid-viewmodel

Is there a difference in creating viewmodel as default argument vs. inside composable body?


Is there a difference between creating a viewmodel as the default value of a composable parameter vs. creating it inside the body of the composable? I don't think there should be any but just wanted to confirm my intuition.

Is there a difference between:

Scenario 1:

@Composable
fun Foo(fooViewModel = viewModel()) {
}

vs.

Scenario 2:

@Composable
fun Foo() {
 val fooViewModel = viewModel()
}

Solution

  • Yes there is. Using first one will break your preview + for both options you gave, you will have to create viewmodel instances when writing tests. Instead, you should either create your viewmodels in your navGraph's composable scope where your compsable placed or wrap your composable with somewhat 'Route' composable that is responsible for creating viewmodel then you should only pass necessary states and function references to your actual screen.

    Here is an example:

    
    fun NavGraphBuilder.profileScreen(
        navigateToPairDetail: (String) -> Unit,
        navigateAndPopUp: (String) -> Unit
    ) {
        composable(ScreenHolder.ProfileScreen.route) {
            val viewModel: ProfileViewModel = hiltViewModel()
            val state by viewModel.state.collectAsStateWithLifecycle()
            val userState by viewModel.userState.collectAsStateWithLifecycle()
            val searchState by viewModel.searchState.collectAsStateWithLifecycle()
            val searchedList by viewModel.searchedPairList.collectAsStateWithLifecycle()
            val uiText = viewModel.eventChannel
            val uiEvent = viewModel.uiEvent
    
            ProfileScreen(
                user = userState ?: User(),
                onEvent = viewModel::onEvent,
                state = state,
                searchedList = searchedList,
                navigate = navigateToPairDetail,
                uiText = uiText,
                uiEvent = uiEvent,
                getAnalyzeCount = viewModel::countOfAnalyze,
                navigateAndPopUp = navigateAndPopUp,
                searhState = searchState
            )
        }
    }