ant2009
ant2009

Reputation: 22486

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.

Upvotes: 6

Views: 6424

Answers (2)

sarthak gupta
sarthak gupta

Reputation: 876

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.

Upvotes: 10

Islam Assem
Islam Assem

Reputation: 1512

I think the error is in that you are setting

    val searchAppBarState: State<SearchAppBarState> = searchAppBarStateMutableState

if you want to share private value as not mutable you shouldn't set it equal rather you can use get modifier

    val searchAppBarState: State<SearchAppBarState> get() = searchAppBarStateMutableState

Also it would be better to name it with underscore as many developers are used to like:

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

Upvotes: 1

Related Questions