처음 만난 react-query (리액트 쿼리) 개념 정리

function_dh·2024년 2월 19일
0
post-thumbnail

리액트 쿼리

1. 리액트 쿼리란?

  • React 환경에서 비동기 Query 과정을 도와주는 라이브러리
    • Query가 뭔가요???
      → 데이터 조회나 조작을 수행하기 위한 질문

2. 왜 사용하는데?

  • 주로 서버에서 비동기적으로 데이터를 가져오거나 업데이트 하는데 사용
  • 리액트에서 서버 상태를 불러오고, 캐싱해서 지속적으로 동기화
  • 리액트 컴포넌트 내부에서 간단하게 사용 가능
  • 리액트 쿼리에서 제공하는 캐싱, Window Focus Refetching 등 다양한 기능을 활용하여 API 요청과 관련된 번잡한 작업 없이 “핵심 로직”에 집중 가능

캐싱

  • 캐싱을 통한 복사본이 존재
    • 따라서 데이터 재접근 속도가 높음
    • 데이터가 동일할 경우 데이터 호출 방지
    • 최신의 데이터를 fresh한 데이터, 기존의 데이터를 stale한 데이터라고 말하는 것을 기억하자

🤔 최신 데이터인지는 어떻게 알어?

  • 실제로 서버 데이터를 불러와 캐싱하고 그 이후에 서버 데이터가 변경 되었다면???
    ⇒ 매우 곤란
  • 따라서 데이터 갱신이 필요하다!

그러면 언제 데이터를 갱신해???

  1. 화면을 보고 있을 때
  2. 페이지의 전환이 일어났을 때
  3. 이벤트가 발생해 데이터를 요청할 때

따라서 리액트 쿼리 옵션에서는 당연히 지원을 하고 있다

refetchOnWindowFocus, // 브라우저에 포커스가 들어온 경우
refetchOnMount, // 새로운 컴포넌트 마운트가 발생한 경우
refetchOnReconnect, // 네트워크 재연결이 발생한 경우
staleTime, //default: 0
gcTime, //default: 5분 (60 * 5 * 1000)

staleTime, gcTime 이건 뭔데요?

staleTime

  • staleTime은 데이터가 fresh → stale 상태로 변경되는 데 걸리는 시간
  • fresh 상태일 때는 트리거가 발생해도 Refetch가 일어나지 않는다!
  • 기본값이 0이라 따로 설정하지 않으면 트리거 발생시 무조건 Refetch 발생
  • 데이터 자체가 fresh한 상태인지 아닌지 여부 체크용도 (stale 상태면 refetch가 이루어진다)

gcTime

  • 캐싱이 된 데이터가 유지되는 시간이다
    → 시간이 지나면? 가비지 콜렉터로 수집되어 메모리에서 삭.제.
  • 컴포넌트가 unmount 되면 사용된 데이터는 inactive 상태로 바뀌고, 이때 데이터는 gcTime만큼 유지한다
  • gcTime 유지 시간동안 해당 데이터를 사용하는 컴포넌트가 다시 mount되면, 새로운 데이터를 fetch해오는 동안 캐싱된 데이터를 보여준다.
  • 즉, 캐싱된 데이터를 계속 보여주는게 아니라 fetch하는 동안 임시로 보여준다는 것

추가로 사용자가 특정 이벤트가 발생했을 때 Refetching을 하도록 설정 가능

Client 데이터와 Server 데이터 간의 분리한다!

  • Client Data: 모달 관련 데이터, 페이지 관련 데이터 등등..
    → 자체적으로 사용하는 상태값이라 생각하면 편하겠죠?
  • Server Data: 사용자 정보, 비즈니스 로직 관련 정보 등등…
    비동기 API 호출을 통해 불러오는 데이터

그럼 왜 기존 상태관리를 사용 안하는데?

  • 대부분 전역상태 라이브러리(redux, recoli)의 경우 Client 데이터를 관리하는데 로직이 집중되어있기 때문!
    → Server 데이터까지 효율적으로 관리하기에는 한계

  • 이러한 문제에 대한 해결책을 보도록 하자

  • queryKey를 통하여 내부적으로 데이터 재요청, 캐싱, 쿼리를 공유하기 위해 사용한다.

    // 컴포넌트 내에서 isPending과 error 상태를 통해
    // 현재 쿼리의 상태를 쉽게 처리할 수 있다!
    function Example() {
      const { isPending, error, data } = useQuery({
        queryKey: ['repoData'],
        queryFn: () =>
          fetch('https://api.github.com/repos/TanStack/query').then((res) =>
            res.json(),
          ),
      })
    
      if (isPending) return 'Loading...'
    
      if (error) return 'An error has occurred: ' + error.message
    
      return (
        <div>
          <h1>{data.name}</h1>
          <p>{data.description}</p>
          <strong>👀 {data.subscribers_count}</strong>{' '}
          <strong>{data.stargazers_count}</strong>{' '}
          <strong>🍴 {data.forks_count}</strong>
        </div>
      )
    }
  • 결론적으로 Client 데이터는 상태 관리 라이브러리가 관리

  • Server 데이터는 리액트 쿼리가 관리하는 구조

  • 짜잔~ Client 데이터와 Server 데이터를 온전하게 분리!!

참고 문헌

profile
🍄 성장형 괴물..

0개의 댓글