Search code examples
kotlinandroid-jetpack-composekotlin-stateflow

Best practice when using mutableState with jetpack compose inside viewmodel with exposing mutable state


I have the following ViewModel

@HiltViewModel
class ShareViewModel @Inject constructor(
    private val taskRepository: TaskRepository
): ViewModel() {

    private val searchAppBarStateMutableState: MutableState<SearchAppBarState> = mutableStateOf(SearchAppBarState.CLOSED)
    val searchAppBarState: State<SearchAppBarState> = searchAppBarStateMutableState

    private val listOfTaskMutableStateFlow = MutableStateFlow<List<TodoTaskEntity>>(emptyList())
    val listOfTaskStateFlow = listOfTaskMutableStateFlow.asStateFlow()
}

I never expose mutableStateFlow as in the example above. And SonarLint will show a warning when doing this.

MutableStateFlow" and "MutableSharedFlow" should not be exposed

So I apply the same technique to the mutableState

However, If I do like this below, I don't get any warning.

val searchAppBarStateMutableState: MutableState<SearchAppBarState> = mutableStateOf(SearchAppBarState.CLOSED)

Just wondering what is the best practice for using MutableState with jetpack compose.


Solution

  • To use mutableState with viewmodel, define mutableState with private setter inside viewmodel, ex -

    var isVisible by mutableState(false)
        private set
    

    By doing above we can read the mutable state from outside of viewmodel but not update it. To update create a public function inside viewmodel, ex -

    fun setVisibility(value: Boolean) {
        isVisible = value
    }
    

    By making a setter function we are following separation of concerns and having a single source of truth for editing the mutableState.