Compose 네트워크 상태 처리

JuYong-Kim·2023년 9월 21일
0

Android 개발 기록

목록 보기
4/4

시작하며

Compose + State를 함께 사용하며 겪은 문제점이 있다. 어떻게 네트워크 상태 처리를 야무지게 하지..? 뷰마다 when(state) 로 관리하는 것은 너무 비효율적이고 중복 코드가 많다. 이를 깎아보자.

호출

UI에서 서버 데이터를 받아오는 예시이다. 호출하면서 viewModel 데이터를 NetworkResult.Loading 으로 바꿔주고 서버 콜이 진행된다. 만약 데이터를 정상적으로 받아왔다면 viewModel 데이터 상태가 NetworkResult.Success 로 바뀌고 안에 있는 필요한 값을 꺼내 쓸 수 있게 된다.

// UI 
    val clothListState by closetViewModel.clothListState.collectAsState()
    var clothList by remember { mutableStateOf(listOf<Cloth>()) }

    LaunchedEffect(Unit) {
        closetViewModel.getClothList()
    }

    NetworkResultHandler(state = clothListState) {
        clothList = it
    }
// viewModel
    private val _clothListState = MutableStateFlow<NetworkResult<List<Cloth>>>(NetworkResult.Idle)
    val clothListState = _clothListState.asStateFlow()
//...
    fun getClothList() = viewModelScope.launch {
        _clothListState.value = NetworkResult.Loading
        _clothListState.emit(getClothListUseCase.invoke(selectedClosetId))
    }

처리

NetworkResult<T> 를 관찰하다가 각 상태에 맞는 처리를 해주면 된다. 이때 제네릭 타입을 인자로 하는 action(data:T) -> Unit 을 넘겨서 UI에서 NetworkResult.SUCCESS 시 필요한 동작을 수행할 수 있도록 한다.

@Composable
fun <T> NetworkResultHandler(state: NetworkResult<T>, action: (data: T) -> Unit) {
    var isLoading by remember { mutableStateOf(false) }
    if(isLoading) {
        GalaxyLoadingView()
    }

    LaunchedEffect(state) {
        when (state) {
            is NetworkResult.Error -> { } // Handle the error here.
            NetworkResult.Idle -> { isLoading = false } // Handle the idle state here.
            NetworkResult.Loading -> { isLoading = true }
            is NetworkResult.Success -> {
                isLoading = false
                action(state.data)
            }
        }
    }
}
profile
Hello World!

0개의 댓글