Alexander Maryanovsky
11/30/2023, 7:21 PM@Composable
fun PrintFlowValue(number: Int, flow: StateFlow<Int>) {
val value by flow.collectAsState()
println("$number $value")
}
val Zero = MutableStateFlow(0)
val One = MutableStateFlow(1)
fun main() = singleWindowApplication {
var flow by remember { mutableStateOf(Zero) }
PrintFlowValue(flow.value, flow)
LaunchedEffect(Unit) {
delay(1000)
flow = One
}
}
eygraber
11/30/2023, 8:11 PM0 0
1 1
andriyo
11/30/2023, 8:13 PMAlexander Maryanovsky
11/30/2023, 8:33 PMAlexander Maryanovsky
11/30/2023, 8:42 PMStateFlow.collectAsState
is essentially implemented like this (details omitted):
@Composable
fun <T> StateFlow<T>.collectAsState(): State<T> = produceState(initialValue = value, this) {
collect { value = it }
}
@Composable
fun <T> produceState(
initialValue: T,
key1: Any?,
producer: suspend ProduceStateScope<T>.() -> Unit
): State<T> {
val result = remember { mutableStateOf(initialValue) }
LaunchedEffect(key1) {
ProduceStateScopeImpl(result, coroutineContext).producer()
}
return result
}
Alexander Maryanovsky
11/30/2023, 8:44 PM@Composable
fun <T> StateFlow<T>.collectAsState(): State<T> {
val result = remember { mutableStateOf(this.value) }
LaunchedEffect(this) {
result.value = this.value
}
return result
}
Pablichjenkov
11/30/2023, 9:13 PMandriyo
11/30/2023, 9:28 PMAlexander Maryanovsky
11/30/2023, 9:30 PMandriyo
11/30/2023, 9:46 PMPablichjenkov
12/01/2023, 3:21 AM0 0
1 0
1 1
What on earthPablichjenkov
12/01/2023, 3:26 AMproduceState
seems the culprit:
val result = remember { mutableStateOf(this.value) }
My theory is it gets the StateFlow from the previous composition and return its value, then after the LaunchEffect runs(after the composition) it updates the StateFlow and return the new value.andriyo
12/01/2023, 5:45 AMPablichjenkov
12/01/2023, 6:04 AMAlexander Maryanovsky
12/01/2023, 6:17 AM@Composable
fun <T> StateFlow<T>.collectAsState(): State<T> {
val result = remember { mutableStateOf(this.value) }
LaunchedEffect(this) {
result.value = this.value
}
return result
}
Alexander Maryanovsky
12/01/2023, 6:17 AMAlexander Maryanovsky
12/01/2023, 6:18 AMAlexander Maryanovsky
12/01/2023, 6:19 AMAlexander Maryanovsky
12/01/2023, 6:20 AMandriyo
12/01/2023, 6:22 AMAlexander Maryanovsky
12/01/2023, 6:25 AMPablichjenkov
12/01/2023, 6:27 AMremember
or LaunchEffect
without keys, is danger.