본문 바로가기
source-code/React

React Query - Placeholder, Initial Data

by mattew4483 2023. 8. 16.
728x90
반응형

React Query initial data

더 나은 사용자 경험 추구는 프론트엔드 개발자의 숙명과도 같다.

이를 위해 수많은 노력을 하게 되는데...
대표적인 사례가 → 서버에서 데이터를 받기 전 화면을 어떻게 그릴 것인가!

일반적으로는 로딩 화면을 보여주면 되지만...
이 역시 '최선의' 방안이라고 보기는 어려울 테다(기다리는 걸 좋아하는 사람은 없으니!)


그렇다면 '최선의' 방안이란 뭘까?
→ 서버 데이터를 받아오기 전에, 화면을 그려주는 건 어떨까?

 

React Query는 이를 위해 여러 유용한 도구들을 제공한다.

prefetchQuery
: 추후 필요한 데이터 미리 가져오기

keepPreviousData
: 쿼리 키가 변경되더라도 마지막으로 success된 data 유지

Placeholder, Initial Data
: use-case에 적합한 데이터를 동기적으로 채워두기

이들 중 Placeholder와 Initial Data를 살펴볼 예정!

공통점

기본적인 사용 방법은 다음과 같다.

	// initialData
    const { data, status } = useQuery(['number'], fetchNumber, {
      initialData: () => 42,
    })

  	// placeholderData
    const { data, status } = useQuery(['number'], fetchNumber, {
      placeholderData: 23,
    })
  1. 둘 다 동기적으로 사용 가능한, 데이터로 캐시를 미리 채우는 방법을 제공한다.
  2. 둘 중 하나가 제공될 경우, 해당 query는 곧바로 loading이 아닌 success 상태가 된다.
  3. value or value를 반환하는 함수 가 올 수 있다.
  4. cache에 이미 데이터가 있는 경우, 아무런 효과가 없다.

차이점

둘의 차이점을 파악하기 위해서는 React Query의 옵션이 어떤 레벨에서 작동하는지 알 필요가 있다.

cache level

각 query key에 대해 하나의 cache entry만 존재한다.
→ React Query는 이를 통해 애플리케이션에서 전역적으로 동일 데이터를 공유할 수 있도록 해줌!

이 때 useQuery에 제공하는 일부 옵션들은 해당 cache entry에 영향을 미친다.
대표적 예시가 바로 staleTime과 cacheTime!
→ cache entry가 하나만 존재하기 때문에,
해당 query가 stale 상태가 되는 시점 및 garbage collector에 의해 수집될 시점을 제어할 수 있다.

observer level

React Query의 observer는 하나의 cache entry에 대해 생성된 구독(subscription)을 의미한다.
해당 observer는 cache entry에서 변경 사항을 확인하고, 변경 사항이 있을 때 마다 알림을 받는다.

observer를 생성하는 기본 방법은? → useQuery를 호출하는 것!
매 호출마다 observer가 생성되며, 데이터가 변경될 때마다 컴포넌트가 re-render된다.
즉... 동일한 cache entry를 바라보는 여러 observer가 존재할 수 있다는 것!
(React Query Devtools 에서 query key 왼쪽의 숫자가 이 observer의 수를 의미한다. 그랬군!)

이러한 observer level에서 동작하는 일부 옵션에는 select, keepPreviousData 등이 있다.

그렇다면... 우리의 initial data와 placeholder 옵션의 차이점은???

initialData 는 cache level에서, placeholderData 는 observer level에서 동작한다!

지속성(Persistence)

initialData는 cache에 유지된다.

cache level에서 동작하기 때문에 initialData는 하나만 존재할 수 있으며,
해당 데이터는 query entry가 생성되는 즉시(첫 번째 observer가 mount될 때) cache에 저장된다!
따라서 다른 initialData로 두 번째 observer를 mount하더라도, 아무 작업이 수행되지 않는다.

반면 placeholderData는 cache에 유지되지 않는다.

즉 해당 데이터는 실제 데이터를 받아오기 전까지 '진짜'가 아닌 것!
React Query는 실제 데이터를 가져오는 동안 placeholderData를 표시할 수 있도록 한다.
또한 observer level에서 동작하기 때문에, 각 컴포넌트 별로 다른 placeholderData를 가질 수 있다.
(이론적으로는) 

Background refetches

initialData는 실제로 cache에 넣은, 유효한 데이터로 간주된다.
따라서 staleTime을 지정한 경우라면,
해당 시점이 지나기 전까지는 해당 query가 server에 요청을 보내지 않는다
= background refetch가 일어나지 않을테다!

placeholderData를 사용하면 observer가 처음으로 mount될 때
항상 background refetch가 일어난다.
해당 데이터는 '진짜'가 아니기 때문에, React Query는 실제 데이터를 fetch하며
이 작업이 진행되는 동안 isPlaceholderData flag도 전달받게 된다.
(실제 데이터가 들어오는 순간, 해당 flag는 false)

error handle

initialData나 placeholderData를 제공한 후, background refetch가 실패한 경우엔 무슨 일이 일어날까?

initialData는 cache에 유지되므로
해당 query는 error 상태가 되지만, cache된 데이터는 유지된다!

반면 placeholderData는...
실제 데이터를 받아오기 전까지 '진짜'가 아닌데, 실제 데이터를 받아오는데 실패했기 때문에
→ query가 error 상태가 되고, data는 undefined가 된다!

728x90
반응형

'source-code > React' 카테고리의 다른 글

Inversion of Control  (0) 2023.08.16
Reconciliation (재조정)  (0) 2023.08.16
React Query - keepPreviousData  (0) 2023.08.15
useReducer  (0) 2023.08.15
useTransition hooks  (0) 2023.08.15