admin管理员组文章数量:1394189
I have a ViewModel that exposes a StateFlow representing the UI state of a book list:
class BooksViewModel(private val getBooksUseCase: GetBooksUseCase) : ViewModel() {
val booksState: Flow<BooksUiState> = flow {
val result = getBooksUseCase()
result.onSuccess {
emit(BooksUiState.Success(it))
}.onFailure {
emit(BooksUiState.Error(it))
}
}.onStart {
emit(BooksUiState.Loading(true))
}.onCompletion {
emit(BooksUiState.Loading(false))
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = BooksUiState.Loading(true),
)
}
In my @Composable
, I collect this state using collectAsStateWithLifecycle
:
@Composable
fun BookScreen(
onBackPressed: () -> Unit,
viewModel: BooksViewModel = koinViewModel()
) {
val uiState by viewModel.booksState.collectAsStateWithLifecycle(
initialValue = BooksUiState.Loading(true)
)
BackHandler(onBack = onBackPressed)
BookContent()
}
Since booksState is already a StateFlow
with an initial value (BooksUiState.Loading(true))
, why do we need to pass initialValue
to collectAsStateWithLifecycle
again?
Is there a way to avoid this redundancy while ensuring correct state collection in Compose?
I have a ViewModel that exposes a StateFlow representing the UI state of a book list:
class BooksViewModel(private val getBooksUseCase: GetBooksUseCase) : ViewModel() {
val booksState: Flow<BooksUiState> = flow {
val result = getBooksUseCase()
result.onSuccess {
emit(BooksUiState.Success(it))
}.onFailure {
emit(BooksUiState.Error(it))
}
}.onStart {
emit(BooksUiState.Loading(true))
}.onCompletion {
emit(BooksUiState.Loading(false))
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = BooksUiState.Loading(true),
)
}
In my @Composable
, I collect this state using collectAsStateWithLifecycle
:
@Composable
fun BookScreen(
onBackPressed: () -> Unit,
viewModel: BooksViewModel = koinViewModel()
) {
val uiState by viewModel.booksState.collectAsStateWithLifecycle(
initialValue = BooksUiState.Loading(true)
)
BackHandler(onBack = onBackPressed)
BookContent()
}
Since booksState is already a StateFlow
with an initial value (BooksUiState.Loading(true))
, why do we need to pass initialValue
to collectAsStateWithLifecycle
again?
Is there a way to avoid this redundancy while ensuring correct state collection in Compose?
Share Improve this question asked Mar 11 at 19:51 Vivek ModiVivek Modi 7,48320 gold badges103 silver badges232 bronze badges 1- 1 There is one that does not need it developer.android/reference/kotlin/androidx/lifecycle/… – tyczj Commented Mar 11 at 20:18
1 Answer
Reset to default 8You declared booksState
to be a Flow<BooksUiState>
, although the actual object is a StateFlow<BooksUiState>
. collectAsStateWithLifecycle()
only sees a regular Flow and that usually has no initial value, so it forces you to provide one.
Just properly declare booksState
as
val booksState: StateFlow<BooksUiState>
Then collectAsStateWithLifecycle()
doesn't need an initial value any more.
本文标签: androidWhy is initialValue needed in collectAsStateWithLifecycle for StateFlowStack Overflow
版权声明:本文标题:android - Why is initialValue needed in collectAsStateWithLifecycle for StateFlow? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744774035a2624516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论