Hi! I’m practicing Compose for desktop and I’m stu...
# compose
s
Hi! I’m practicing Compose for desktop and I’m stuck with the problem: I have “screenState: StateFlow” value with state for my UI (sealed class) From UI I use default approach “screenState.collectAsFlow()” to trigger recomposition if state changes and I have method “subscribe(chatRoom: ChatRoom)” in my ApplicationController (aka view model for desktop) which calls to a useCase and returns Flow<Message>. Emitter takes my state and makes a copy with a new message but from time to time Compose ignores (or misses) new state value. Screenshots in thread.
Compose state
state in the application controller
collector
_screenState.value = current.copy(messages = updatedList)
Is being triggered every time, but there is no recomposition sometimes
n
You might want to try and ask here: #compose-desktop
f
StateFlow
emits only "new" values based on equality so make sure you don't emit the same instance. In addition to that
StateFlow
conflates emits if they happen too quickly but it should always emit the latest value.
s
I believe that .copy() creates new reference but I'll check it anyway Not the second one for sure. First state after default is always missing.
f
Copy does create new instance but maybe
equals
method returns true. Is
ScreenState
data class?
s
@Filip Wiesner ScreenState is sealed, but underlying class with list of messages is indeed "data" class.
Seems like state.value is working nice because if I change “val text: String” right after new message is set - recompose happens and I see the new message. But message should be visible right after “Enter” pressed
f
As a general rule state should never be mutable. Try creating new messages (non-mutable) list for each
InRoom
state change because I still think the problem is in the equality method. Or maybe swap StateFlow for SharedFlow.
Oh, I see you solved your problem in #compose-desktop
s
Yep, seems like List can affect state change. Thank you for help!
🙌 1