My solution is to support repeated messages/errors and don't show one message/error multiple times. Recomposition will be called just ones
1.Create a smart delegate that removes the value after reading. It is the main logic
class OnceReadDelegate<T>(private var value: T? = null) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { val currentValue = value value = null return currentValue } operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) { value = newValue } }
2.Create a Message class that manages our text and type of message
class Message { var payload by OnceReadDelegate<String?>() var type: MessageType = MessageType.Error companion object { fun create(text: String?, messageType: MessageType = MessageType.Error) = Message().apply { payload = text this.type = messageType } } } sealed class MessageType { data object Regular : MessageType() data object Error : MessageType() }
3.My example of state class with our Message class
data class SettingsPageState( val listWidgetState: List<WidgetViewState> = emptyList(), val listAgeFormat: List<AgeFormat> = emptyList(), val message: Message? = null, val isLoading: Boolean = true, val isEmpty: Boolean = false )
4.My example of updatin the state with a new message
mutableState.update { previousState -> previousState.copy(message = Message.create(exception?.message)) }
5.And finally Composable function how to how Snackbar
@Composable fun SettingsScreen() { ... LaunchedEffect(state.message) { val text = state.message?.payload if (!text.isNullOrEmpty()) { //your method to show snackbar onShowSnackbar(text , null) } } ... }
It is all)