如何解决StateFlow值不更新的问题?

问题描述 投票:0回答:1

如何解决 StateFlow 值不更新的问题?

  • StateFlow 的值未分配给 BoardRequestDto 对象。
  • createPost 函数中未正确收集 StateFlow 的最新值。
// PostBoardViewModel.kt
@HiltViewModel
class PostBoardViewModel @Inject constructor(
    private val boardRepository: BoardRepository,
) : ViewModel() {
    private val _uiState = MutableStateFlow<PostBoardUiState>(PostBoardUiState.Initial)
    val uiState: StateFlow<PostBoardUiState> = _uiState

    private val _title = MutableStateFlow("")
    val title: StateFlow<String> = _title
    
    private lateinit var boardRequestDto: BoardRequestDto

    private fun updateTitle(newTitle: String) {
        _title.value = newTitle
        Log.d("PostBoardViewModel", "Title updated: ${title.value}")
    }

    private fun createPost() {
        viewModelScope.launch {
            _uiState.value = PostBoardUiState.Loading

            boardRequestDto = BoardRequestDto(
                title = title.value,
                // ...
            )

            Log.d("PostBoardViewModel", "BoardRequestDto created: $boardRequestDto")

            try {
                Log.d("PostBoardViewModel", "Attempting to post board")

                val result = boardRepository.postBoard(boardRequestDto)
                Log.d("PostBoardViewModel", "API response: $result")

                when {
                    result.data != null -> {
                        val boardIdDto = result.data
                        _createdBoardIds.value += boardIdDto!!.boardId
                        _uiState.value = PostBoardUiState.Success(boardIdDto)
                        Log.d(
                            "PostBoardViewModel",
                            "Post created successfully with ID: ${boardIdDto.boardId}"
                        )
                    }

                    result.error != null -> {
                        val errorMessage = result.error!!.message
                        _uiState.value = PostBoardUiState.Error(errorMessage)
                        Log.e("PostBoardViewModel", "Error creating post: $errorMessage")
                    }

                    else -> {
                        _uiState.value = PostBoardUiState.Error("unknown error")
                        Log.e(
                            "PostBoardViewModel",
                            "Unknown error occurred while creating post"
                        )
                    }
                }
            } catch (e: Exception) {
                _uiState.value = PostBoardUiState.Error("netword error: ${e.message}")
                Log.e("PostBoardViewModel", "Exception while creating post", e)
            }
        }
    }
}

// Enum class: PreferredGender, PreferredAge, Region, Category, BoardStatus
enum class PreferredGender {
    SAME, ANY
}
// BoardRepository.kt
interface BoardRepository {
    suspend fun postBoard(board: BoardRequestDto): ResultResponse<BoardIdDto>
}

// ResultResponse
data class ResultResponse<T>(
    var data: T? = null,
    var error: ResponseError? = null
)

@Serializable
data class ResponseError(
    val status: Int,
    val code: String,
    val message: String
)

// BoardRequestDto.kt
@Serializable
data class BoardRequestDto(
    val title: String,
    // ...
)

// BoardIdDto.kt
@Serializable
data class BoardIdDto(
    val boardId: Int
)

// PostBoardIntent.kt
sealed class PostBoardIntent {
    data object CreatePost : PostBoardIntent()
}
// PostBoardScreen.kt
@Composable
fun PostBoardScreen(
    viewModel: PostBoardViewModel = hiltViewModel()
) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    val title by viewModel.title.collectAsStateWithLifecycle()

    when(uiState) {
        is PostBoardUiState.Initial ->
            Column {
                AccompanyTitleInput(
                    title = title,
                    onTitleChange = {
                        viewModel.handleIntent(PostBoardIntent.UpdateTitle(it))
                    }
                )
                // ...
            }
        is PostBoardUiState.Loading -> CircularProgressIndicator()
        is PostBoardUiState.Success ->
            Column {
                AccompanyTitleInput(
                    title = title,
                    onTitleChange = {
                        viewModel.handleIntent(PostBoardIntent.UpdateTitle(it))
                    }
                )
                // ...
            }
    }
    // Receives a value for each item from the user
    // When you click the post button on the top bar, a post is created.
}
// GetTopBar Function in MainActivity.kt (app module)
@Composable
fun GetTopBar(
    currentRoute: String?,
    navController: NavHostController
) {
    val viewModel: PostBoardViewModel = hiltViewModel()
    
    // TopAppBar of PostBoardScreen
    Screen.Post.route -> {
            BackButtonWithTitleTopAppBar(
                screenTitle = "동행 모집하기",
                onNavigateUp = { navController.navigateUp() },
                onPostClick = {
                    viewModel.handleIntent(PostBoardIntent.CreatePost)
                    navController.navigate(Screen.Home.route)
                }
            )
        }
    }
}

我如何尝试

  • 即使使用
    combine
    collectLatest
    ,也不会收集值。
  • 调用前检查该值是否设置正确
    createPost
    -> 设置正确
  • 直到调用
    createPost
    函数之前,都会检查
    StateFlow
    值是否为最新值,但在函数内将其设置为初始值。
  • Copilot 和 GPT 并不能解决问题
android kotlin android-jetpack-compose viewmodel stateflow
1个回答
0
投票

您不会在任何地方调用您的

PostBoardViewModel.createPost()
函数。

也许,这就是原因?

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.