StateFlow vs SharedFlow

StateFlow represents the latest state and always has a current value. SharedFlow broadcasts values to active collectors and can be configured for replay and buffering.

Practical guidance

  • Use StateFlow for renderable UI state.
  • Use SharedFlow for broadcasts where replay semantics are intentional.
  • Model navigation or messages carefully; persistent UI state is often safer than one-shot events.
  • Collect with repeatOnLifecycle or collectAsStateWithLifecycle.

Working example

private val _state = MutableStateFlow(ScreenState())
val state = _state.asStateFlow()

private val _events = MutableSharedFlow<ScreenEvent>(extraBufferCapacity = 1)
val events = _events.asSharedFlow()

_state.update { it.copy(loading = false) }
_events.tryEmit(ScreenEvent.Saved)

Common mistakes

  • A SharedFlow with replay can repeat navigation after recreation.
  • StateFlow suppresses equal consecutive values.
  • Collecting without lifecycle control keeps upstream work active unnecessarily.

Key takeaway

If a new collector needs the current answer immediately, start with StateFlow. Use SharedFlow when the stream itself—not a current value—is the abstraction.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top