React Query Placeholder와 initData

이재철·2023년 3월 2일
3

react-query

목록 보기
9/12
post-thumbnail

Placeholder and initial Data in React Query

react query를 사용하여 사용자 경험을 개선하는 방법에 대해서 알아보자.
➡ 대부분은 사람(유저)들은 Loading Spinner 를 싫어 합니다. 🤬

react query는 서로 다르지만 유사한 방법으로 Placeholder Query DataInitial Query Data 의 두 가지 방법을 제공합니다.

Similarities

데이터를 캐시에 동기적으로 미리 채울 수 있는 방법을 제공합니다.
➡ 쿼리가 로딩 상태가 아닌 바로 성공 상태로 전환됩니다.

function Component() {
  // ✅ status will be success even if we have not yet fetched data
  const { data, status } = useQuery(['number'], fetchNumber, {
    placeholderData: 23,
  })

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

캐시에 데이터가 이미 있는 경우 둘 다 영향을 미치지 않습니다.

On cache level

각 쿼리 키에는 캐시 항목이 하나만 있습니다.
➡ react query가 애플리케이션에서 동일한 데이터를 전역적으로 공유할 수 있기 때문입니다.

staleTimecacheTime 에 영향을 미치며 옵션에 따라 GC 될 수 있는 시기를 설정 할 수 있습니다.

On observer level

react query의 observer 는 하나의 캐시 엔트리를 위해 생성된 subscription 입니다.
observer 는 캐시 항목이 변경되었는지 확인하고 변경 사항이 있는 경우 알림을 받습니다.

React Query Devtools

React Query Devtools 에서 쿼리 키 왼쪽의 숫자는 (1) 쿼리에 포함된 observer 수를 확인 할 수 있습니다.

  • observer 는 useQuery를 호출하면 생성됩니다.
    ➡ 호출 할 때마다 observer 을 만들고 데이터가 변경되면 컴포넌트가 다시 렌더링됩니다.
    💡 동일한 캐시 항목을 보는 여러 observer 가 있을 수 있다.

Differences

  • InitialData : 캐시 수준에서 동작
  • placeholderData : observer level 에서 동작

Persistence (영속성)

initialData

initialData 는 캐시에 유지됩니다.

캐시 수준에서 작동하기 때문에 하나의 initialData 만 있을 수 있으며, 캐시 항목이 생성되는 즉시(첫 번재 관찰자가 마운트될 때) 캐시에 저장됩니다.

🚨 다른 initialData로 두 번째 observer 를 마운트하려고 하면 아무 작업도 수행하지 않습니다.


PlaceholderData

PlaceholderData 는 캐시에 유지되지 않습니다.

해당 데이터는 서버 데이터와 관련 없는 보여주기용 가짜 데이터 입니다.
react query는 실제 데이터를 가져오는 동안 해당 데이터를 보여줍니다.

observer 수준에서 작동하기 때문에 이론적으로 다른 컴포넌트에 대해 다른 placehoderData 를 가질 수 있습니다.

Background refetches

initialData

initialData 는 캐시에 유효한 데이터로 간주되므로 실제로 저장되어 오랜 시간 남아 있습니다.
만약 staleTime 이 0(기본값) 이라면 background-refetch 를 확인할 수 있습니다.

쿼리에 staleTime(ex 30초) 를 설정한 경우 초기 데이터를 동기적으로 얻을 수 있으며, 해당 데이터는 30초간 유효하기 때문에 backend에 요청할 필요가 없습니다.

initialDataUpdatedAt 을 사용하여 해결 할 수 있습니다.
initailData 가 생성되었을 때 react query에 알리며 고려하여 백그라운드 다시 가져오기가 트리거 됩니다.

기존 캐시 항목에서 dataUpdatedAt 타임스탬프와 initialData 를 사용할 때 매우 유용합니다.

const useTodo = (id) => {
  const queryClient = useQueryClient()

  return useQuery(['todo', id], () => fetchTodo(id), {
    staleTime: 30 * 1000,
    initialData: () =>
      queryClient
        .getQueryData(['todo', 'list'])
        ?.find((todo) => todo.id === id),
    initialDataUpdatedAt: () =>
	// ✅ initial data를 채우는데 사용한 쿼리 데이터가 
    // staleTime(30초) 더 오래된 경우 백그라운드에서 다시 가져옵니다.
      queryClient.getQueryState(['todo', 'list'])?.dataUpdatedAt,
  })
}

PlaceholderData

PlaceholderData 를 사용하면 처음으로 관찰자를 탑재할 때 항상 백그라운드에서 다시 가져옵니다.
➡ 데이터가 실제 데이터가 아니므로 react query가 실제 데이터를 가져옵니다.

데이터를 가저오는 동안 react query에서 반환된 isPlaceholderData 플래그를 얻을 수 있습니다.
✅ 이 플레그를 사용하여 사용자가 보고 있는 데이터가 실제로는 PlaceholderData 임을 시각적으로 알 수 있습니다.
➡ 실제 데이터가 들어오는 즉시 false 로 전환됩니다.

Error transitions

initailData 또는 PlaceholderData 사용 시, 백그라운드 리페치가 트리거된 다음, 쿼리가 실패한다는 가정을 새워봅니다. 어떤 상황이 발생할까요?

initialData

initailData 는 캐시에 유지되므로 refetch 오류는 다른 백그라운드 오류와 같이 처리됩니다.
➡ 쿼리는 오류 상태이지만 데이터는 여전히 존재함


PlaceholderData

쿼리는 error 상태가 되며 데이터는 undefined 가 됩니다.

언제 무엇을 사용해야 할까?

  • 다른 쿼리로 부터 쿼리를 미리 채울 때 initialData
  • 그 외 placeholderData

참조 링크

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글