Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 961
Andi Kitta Avatar asked Oct 22 '25 20:10

Andi Kitta


1 Answers

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.

like image 107
Arpit Shukla Avatar answered Oct 25 '25 11:10

Arpit Shukla