В чем разница StateFlow и Compose State
Что проверяют
Понимаете ли вы, что это инструменты разных слоёв с разной механикой, и умеете ли их связывать. Следом обычно спрашивают, что держать во ViewModel и чем collectAsState() отличается от collectAsStateWithLifecycle().
Как отвечать
Начните с природы каждого:
StateFlow: горячий поток из kotlinx.coroutines, всегда хранит текущее значение и сразу отдаёт его новому подписчику. Сливает промежуточные значения и не эмитит, если новое равно старому поequals. К Compose не привязан, работает в любом слое;- Compose State (
mutableStateOf,State<T>): часть снапшот-системы рантайма Compose. Composable, прочитавший значение, подписывается автоматически, и при изменении перекомпонуется только он. Безrememberзначение пересоздаётся на каждой рекомпозиции, а пережить поворот экрана без ViewModel помогаетrememberSaveable.
Типовая схема: ViewModel держит StateFlow<UiState>, собранный через combine, map и stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), initial), а экран превращает его в Compose State через collectAsStateWithLifecycle(). Этот вариант останавливает сбор, когда экран опускается ниже STARTED, а обычный collectAsState() продолжает собирать поток в фоне. Обратный мост: snapshotFlow { } превращает чтение Compose State во Flow.
Почему не mutableStateOf во ViewModel: так делать можно, но ViewModel начинает зависеть от рантайма Compose, теряются операторы потоков, а StateFlow удобнее тестировать через Turbine. Локальное состояние интерфейса, раскрыт ли блок или что введено в поле, это место для remember { mutableStateOf(false) }.
Где спотыкаются
Кладут в состояние изменяемую коллекцию и меняют её на месте. И StateFlow, и mutableStateOf видят ту же ссылку и ничего не сообщают. Нужны неизменяемые копии через update { it.copy(...) } или mutableStateListOf.
Передают через StateFlow одноразовые события вроде навигации или тоста. Состояние сливает значения и повторно отдаёт последнее после пересоздания экрана, поэтому событие срабатывает дважды или теряется.
Собирают поток через collectAsState() и получают сбор в фоне. На Android нужен вариант с учётом жизненного цикла.