Paging3 아이템 삭제하기

covy·2024년 5월 21일
post-thumbnail

서론

이번 Paging3를 사용하면서, 생각보다 리스트 변경에 대한 가이드가 부족해 보였다.

왜 부족한가?

  • Paging 데이터가 불변이다. 네트워크, Dao, 에러상황등을 일관되게 다루기 위해서 불변으로 PagingData등 불변 값으로 설정되어 있어, 이를 수정하기 어렵다.
  • 실제로 단순하게 페이징을 구현하기 위한 라이브러리로, Read면에서는 확실히 편하게 구현 가능하다. 다만 편한만큼, 추상화 레벨이 깊다. 그래서 데이터 상태 변경이 어렵다

어떤 방법을 쓸 것인가?

서칭해보았을 때 답변들을 보면 아래와 같은 방법으로 추려졌다.
1. removedList를 관리해서 현재 리스트에 필터링 거는 것
2. Dao를 써서 해결할 수 있게 Paging3가 설계 되었음

2번도 공부해보면서 적용할만 했지만, 내부 캐싱까지 구현하는 것은 오버 엔지니어링이어서 디테일 화면에서 넘어오는 삭제 ID 또는 아이템을 리스트 화면에서 받아, removedList를 구현하기로 결정하였다.

시나리오

list 화면에서 savedInstance data가 들어오면, 이를 deleted List에 추가한다. 이후 List - deletedList 하여 사용자에게 보여준다.

고려사항

flow zip vs combine

zip 같은 경우 새로운 deletedId가 와도 다음 post 호출 값을 기다리고 있기 때문에 작동 안할 것이다. 반대 상황 역시 단점이 된다.

combine이 적절해보인다.

PagingData.filter 성능

filter를 통한 PagingData 전체 순회를 해서 O(n X m) 만큼 비용이 발생한다.

코드

private val deletedIdsFlow = MutableStateFlow(setOf<Long>())

    val postListPagingFlow = combine(_postListPagingFlow, deletedIdsFlow) { paging, deletedPostId ->
        paging.filter {
            deletedPostId.contains(it.postId).not()
        }
    }.cachedIn(viewModelScope)
    init {
        fetchPostList(currentTopic.value)
    }

후기

Paging3를 이번 프로젝트에 처음 적용시켜보았다. Read만 하는 경우 확실히 편한 것 같다 (무한 스크롤 자동 구현, 중복 호출 방지등의 메리트)
다만 그 외에 상황에서는 조금 고민이 되는 것 같다.

그 이유로 현재 상황에서 아이템을 제거하기 위한 탐색 비용 및 추가적인 필드가 생겼다.

더 복잡한 상황에서는.. 음..

0개의 댓글