androidandroid-jetpack-composekotlin-flowmutablestateof

Why snapshotFlow is trigged with MutableState as property delegate?


I have a situation with the snapshotFlow recently when trying to observe changes from a MutableState. Here is the snippet

val searchQuery = mutableStateOf("")
snapshotFlow { searchQuery }.collectLatest {
               
}

But when the searchQuery changed, there was nothing happened in collectLatest block. It seems the snapshotFlow not find any changes from searchQuery. I guessed. Then I changed the searchQuery declare to var searchQuery by mutableStateOf(""). The snapshotFlow works as expected. Can anyone explain me why? Really appreciate!


Solution

  • Please refer to this StackOverflow answer:

    SnapshotFlow works similarly to recomposition - it tracks reads of State.value to know when to emit. So for snapshotFlow to work, the value has to be read inside of the snapshotFlow {} block, which is not happening

    With your current approach, the snapshotFlow doesn't know which changes to observe. When using the by keyword, searchQuery.value is implicitly called, and thus the snaphotFlow can detect the changes.

    To solve this, please try

    val searchQuery = mutableStateOf("")
    snapshotFlow { searchQuery.value }.collectLatest {
        // ...      
    }
    

    or use the by keyword.

    As the official documentation remains vague about how the approaches for declaring a MutableState differ, this Reddit post summarizes the differences well.