Andi Kitta
Andi Kitta

Reputation: 61

What is the difference between _uiState.asStateFlow() and StateFlow<UIState> = _uiState in ViewModel Jetpack Compose

private val _uiState = MutableStateFlow(AdaptiveHomeUIState(loading = true))
val uiState: StateFlow<AdaptiveHomeUIState> = _uiState
val uiState2 = _uiState.asStateFlow()

The above code shows two different public uiState. Which are uiState and uiState2. what exactly the difference between?, if it just the same. Which is the best recommended way?

Upvotes: 4

Views: 1141

Answers (1)

Arpit Shukla
Arpit Shukla

Reputation: 10523

The reason we use a combination of mutable private state (_uiState) and a read-only public state (uiState and uiState2) is so that the consumers of the state cannot change the state. In your particular example, these flows are most probably created inside a ViewModel and will be exposed to UI for consumption. We don't want the UI to be able to change the value in the MutableStateFlow, that's why we only expose a read-only StateFlow.

The difference between uiState and uiState2 is that uiState can be converted back to a MutableStateFlow by type casting while uiState2 cannot be. For example,

val flow1 = MutableStateFlow(1)
val flow2: StateFlow<Int> = flow1
println(flow1.value)
(flow2 as MutableStateFlow).value = 2  // Changing the value of `flow2`
println(flow1.value)

Output:

1
2

As you can see, one can change the value of flow1 using flow2 because they essentially point to the same object which can be seen in below example:

val flow1 = MutableStateFlow(1)
val flow2: StateFlow<Int> = flow1
val flow3 = flow1.asStateFlow()
println(flow1)
println(flow2)
println(flow3)

Output:

kotlinx.coroutines.flow.StateFlowImpl@41629346
kotlinx.coroutines.flow.StateFlowImpl@41629346
kotlinx.coroutines.flow.ReadonlyStateFlow@404b9385

So, it's better to use .asStateFlow() here.

Upvotes: 3

Related Questions