[Ngether] react-query를 사용한 채팅 리스트 페이지 구현

hzn·2023년 4월 7일
0

PROJECT🏝

목록 보기
14/24
post-thumbnail
post-custom-banner

react-query를 사용한 채팅 리스트 페이지 구현

🍉 쿼리 인스턴스 생성

  • useQuery를 사용해 내가 참여한 공동구매(채팅) 목록 데이터인 mySharings 쿼리 인스턴스 생성

default options

  • 쿼리 생성 시 따로 옵션을 지정하지 않으면 기본값은 다음과 같이 설정된다
staleTime : 0  // 캐싱된 데이터는 언제나 stale 상태
cachTime : 60 * 5 * 1000 (5) // inactive 상태가 된 후 5분 뒤 GC에 의해 처리
refetchOnMount, refetchOnWindowFocus, refetchOnReconnect : true // 각 시점에서 데이터가 stale 상태라면 항상 refetch
retry : 3 // 쿼리 실패 시 3번까지 retry 발생
retryDelay : exponentiall backoff function

🍐 채팅 리스트 페이지의 Server State

  • 모집 상태(recruitment) : 모집중 또는 모집 완료를 나타내는 데이터
  • 마지막 메시지(lastMessage) : 가장 마지막에 전송된 메시지
  • 안 읽은 메시지 개수(unreadCount) : 해당 유저가 확인하지 않은 메시지의 개수

  • 그 외 제목이나 제품 이미지, 위치 등도 개설자가 수정해 서버 데이터를 바꾸면 변경되는 Server State이다.

Client State vs. Server State

  • 데이터의 제어권이 어디에 있는지에 따라 나뉜다.

Client State

  • 다른 사람과 공유되지 않음.
  • Client 내에서 최신 상태로 관리됨
  • ex) 배경 모드, 장바구니 상태...

Server State

  • Fetching/Updating에 비동기 API가 필요
  • 다른 사람들과 공유됨.
  • 유저가 모르는 사이에 서버 데이터가 변경될 수 있음. (유저가 보고있는 데이터는 out of date일 가능성이 있음)
  • ex) 배달 앱 주문 데이터(주문 완료/준비중/배달중)

🍇 로딩, 에러 처리하기

  • useQuery를 이용해 구조분해할당으로 data 외에도 isLoading, isError, error 등을 받아와 편리하게 사용할 수 있다.

🍑 react-query dev tools

  • _app.tsx 파일에서 ReactQueryDevtools를 불러와서 넣어준다.

_app.tsx

import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; // 불러오기
...
return (
    <>
      <Head>
        <title>Ngether</title>
      </Head>
      <QueryClientProvider client={queryClient}>
        ...
          {renderWithLayout(<Component {...pageProps} />
          )}
        ...
        <ReactQueryDevtools initialIsOpen={false} /> // 넣어주기
      </QueryClientProvider>
    </>
  );

🍊 cache 업데이트 시점 지정하기

  • 채팅 특성 상 마지막 메시지안 읽은 메시지 개수 데이터의 업데이트가 수시로 일어나므로 default 값인 staleTime : 0을 유지해 데이터를 받아오는 즉시 stale 상태가 되도록 했다.
  • 이제 refetch 이벤트가 발생할 때마다 서버의 새 데이터로 캐시가 업데이트된다.

refetchInterval로 자동 업데이트 (➡️ 사용 X)

  • refetchInterval option을 사용해 계속해서 업데이트된 데이터가 보여지는 방식도 고려해 보았으나...
  • react-query를 사용하는 이유 중 하나가 데이터 캐싱으로 최대한 API 콜을 줄여서 서버의 부담을 줄여보자는 것이었는데 계속해서 refetch 하는게 서버에 부담이 갈 것 같아 적용하지 않기로 했다.

실제 채팅 서비스처럼 그럴 듯해 보인다는 점이 매력적이었지만...서버가 아파 보여서 관뒀다

🥑 결과물

  • refetchInterval을 설정하지 않은 경우 새 채팅 메시지가 올라왔을 때 채팅 리스트 페이지에 다시 windowFocus 해주면(refetchOnWindowFocus : true) 마지막 메시지가 업데이트된다.

레퍼런스

post-custom-banner

0개의 댓글