프론트엔드/React

React Query - 기능구현

학습하는 청년 2024. 7. 25. 12:41

최종 수정일 : 2024-07-25

기능구현

Dependant Query

만약 어떤 두 쿼리가 의존관계가 있어 특정 순서대로 실행이 되어야 하는 경우에는 useQuery()의 enabled 옵션을 사용할 수 있다. enabled 옵션을 사용하면 enabled 값이 true가 되어야만 해당 쿼리가 실행된다. 이렇게 어떤 특정 값이나 조건이 충족된 이후에 실행되는 쿼리를 Dependant Query라고 한다.


Paginated Query

리액트 쿼리에서는 좀 더 부드러운 UI 전환을 위해 placeholderData 라는 것을 설정해줄 수 있다. useQuery()에서 placeholderData 옵션에 keepPreviousData 혹은 (prevData) => prevData를 넣어주면 페이지가 새로 바뀌더라도 매번 pending 상태가 되지 않고, 이전의 데이터를 유지해서 보여주다가 새로운 데이터 fetch가 완료되면 자연스럽게 새로운 데이터로 바꿔서 보여준다.

 

이때, 유의해야 핳 점은 현재 보이는 데이터가 이전 데이터, 즉 placeholderData라면 다음 페이지 버튼을 비활성해주는 것이 좋다. 그렇지 않으면 유저가 다음 페이지 버튼을 마구 누르는 경우, 존재하지 않은 페이지로 리퀘스트가 갈 수도 있기 때문이다. 이것은 useQuery()의 리턴 값에서 isPlaceholderData 값을 활용하면 된다.


Infinite Query

useInfiniteQuery()가 어떻게 동작하는지 살펴보자. useQuery()에서는 data가 백엔드에서 받아 온 하나의 페이지 정보만 담고 잇지만, useInfiniteQuery()에서는 data.pages에 배열의 형태로 모든 페이지의 정보를 담고 있게 된다. 첫 페이지의 정보는 배열의 0번 인덱스에 해당 데이터가 저장되고, 다음 페이지의 정보는 1번 인덱스에 저장되는 것이다. 이런 식으로 배열에 데이터들이 모두 담겨있으므로 데이터를 한 번에 화면에 보여줄 수 있는 것이다. 이 데이터들은 ['posts']라는 하나의 쿼리 키로 캐싱된다.

 

pageParam 사용하기

initialPageParam: 0,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
  lastPage.hasMore ? lastPageParam + 1 : undefined,

initialPageParam으로는 초기 페이지 설정값을 정하게 된다. 사용하는 API에는 0 페이지가 초기 페이지이면 값을 0으로 설정하면 된다.

 

그리고 getNextPageParam() 함수로는 다음 페이지의 설정값을 정하게 된다. lastPage, allPages, lastPageParam, allPageParams를 파라미터로 전달받는다.


Optimistic Updates

ex) 좋아요 기능, 프로필 업데이트, To-Do 리스트에 아이템 추가

'좋아요' 기능과 같이 유저에게 빠른 피드백을 제공해야 하는 경우에 사용한다. 간단히 말해 서버로부터의 리스폰스를 기다리지 않고 유저에게 바로 낙관적인 피드백을 주는 것을 말한다. 서버가 제대로 동작하는 걸 낙관적으로 기대한다고 말할 수 있다. 예를 들어, '좋아요' 버튼을 눌렀을 때 실제로 서버에 반영이 제대로 되었는지 확인하지 않고 유저에게 바로 '좋아요' 버튼을 누른 것처럼 버튼을 활성화해서 보여주는 것이다.

 

이렇게 해도 괜찮은 이유는 리퀘스트는 보통 99% 이상의 활률로 서버에 제대로 반영될 것이고, 또한 만에 하나 중간에 에러가 발생한다고 해도 치명적인 결함이 아니기 때문이다. 글로만 접했을 때는, 신뢰가 다소 떨어질 수 있지만 매번 서버의 리스폰스를 기다리느라 유저에게 답답함을 주기보다는 옵티미스틱 업데이트를 이용해 빠른 피드백을 제공하는 것이 더 좋다.

 

이를 useMutation()의 onMutate, onError, onsetteld 옵셥을 활용해 구현할 수 있다.

  • onMutate
    1. 옵티미스틱 업데이트를 통해 변경하려고 하는 데이터가 refetch로 인해 덮어씌워지는 것을 막기 위해 cancelQueries()를 실행하여, 좋아요 관련 데이터를 받아 오지 않도록 쿼리를 취소해 준다.
    2. 에러가 발생했을 때는 이전의 데이터로 롤백해줘야 하므로 이를 따로 저장해 준다.
    3. 원하는 값으로 쿼리 데이터를 미리 변경한다.
    4. 롤백용 데이터를 리턴해 준다.
  • onError
    롤백용 데이터를 세 번째 파라미터인 context로 받아 온다. context 값으로 쿼리 데이터를 변경해 준다.
  • onSettled
    에러 여부와 상관없이 백엔드 서버와 데이터를 동기화해주기 위해 좋아요 관련 데이터 쿼리를 invalidate해 준다.