본문으로 건너뛰기

플레이스홀더 쿼리 데이터

플레이스홀더 데이터란 무엇인가요?

Placeholder 데이터는 initialData 옵션과 유사하게 쿼리가 이미 데이터를 보유한 것처럼 동작하도록 하지만, 해당 데이터는 캐시에 영구 저장되지 않습니다. 이는 실제 데이터를 백그라운드에서 가져오는 동안 쿼리를 성공적으로 렌더링할 만큼 충분한 부분 데이터(또는 가짜 데이터)가 있는 상황에 유용합니다.

예: 개별 블로그 게시물 쿼리는 제목과 게시물 본문의 짧은 일부만 포함하는 상위 블로그 게시물 목록에서 "미리보기" 데이터를 가져올 수 있습니다. 이 부분 데이터를 개별 쿼리의 쿼리 결과에 영구 저장하고 싶지는 않겠지만, 실제 쿼리가 전체 객체 가져오기를 완료하는 동안 콘텐츠 레이아웃을 최대한 빠르게 표시하는 데 유용합니다.

쿼리가 필요해지기 전에 캐시에 쿼리의 플레이스홀더 데이터를 제공하는 방법은 몇 가지가 있습니다:

placeholderData를 사용하면 Query는 pending 상태가 아니라 success 상태로 시작합니다. 표시할 data가 있기 때문이며, 해당 데이터가 단지 "플레이스홀더" 데이터인 경우에도 마찬가지입니다. 이를 "실제" 데이터와 구분하기 위해 Query 결과의 isPlaceholderData 플래그도 true로 설정됩니다.

값으로 사용하는 플레이스홀더 데이터

function Todos() {
const result = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/todos'),
placeholderData: placeholderTodos,
})
}

자리표시자 데이터 메모이제이션

쿼리의 플레이스홀더 데이터에 접근하는 과정이 집약적이거나 매번 렌더링할 때 수행하고 싶지 않다면 값을 메모이제이션할 수 있습니다:

function Todos() {
const placeholderData = useMemo(() => generateFakeTodos(), [])
const result = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/todos'),
placeholderData,
})
}

함수로 사용하는 플레이스홀더 데이터

placeholderData는 함수일 수도 있으며, 이 함수에서는 "이전"에 성공한 Query의 데이터와 Query 메타 정보에 접근할 수 있습니다. 이는 한 쿼리의 데이터를 다른 쿼리의 플레이스홀더 데이터로 사용하려는 상황에 유용합니다. QueryKey가 예를 들어 ['todos', 1]에서 ['todos', 2]로 변경될 때, 데이터가 한 Query에서 다음 Query로 전환되는 동안 로딩 스피너를 표시하는 대신 "이전" 데이터를 계속 표시할 수 있습니다. 자세한 내용은 페이지가 매겨진 쿼리를 참조하세요.

const result = useQuery({
queryKey: ['todos', id],
queryFn: () => fetch(`/todos/${id}`),
placeholderData: (previousData, previousQuery) => previousData,
})

캐시에서 가져오는 플레이스홀더 데이터

경우에 따라 한 쿼리의 placeholder 데이터를 다른 쿼리의 캐시된 결과에서 제공할 수 있습니다. 좋은 예로, 블로그 게시물 목록 쿼리의 캐시된 데이터에서 게시물의 미리보기 버전을 검색한 다음 이를 개별 게시물 쿼리의 placeholder 데이터로 사용하는 경우가 있습니다:

function BlogPost({ blogPostId }) {
const queryClient = useQueryClient()
const result = useQuery({
queryKey: ['blogPost', blogPostId],
queryFn: () => fetch(`/blogPosts/${blogPostId}`),
placeholderData: () => {
// Use the smaller/preview version of the blogPost from the 'blogPosts'
// query as the placeholder data for this blogPost query
return queryClient
.getQueryData(['blogPosts'])
?.find((d) => d.id === blogPostId)
},
})
}

추가 자료

Placeholder DataInitial Data의 비교는 TkDodo의 문서를 참조하세요.