Reputation: 61
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
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