Initial Query Data
TanStack Query에는 초기데이터를 활용하는 두가지 방법이 있다.
- 선언형
'initialData'를 쿼리에 선언하여, 쿼리가 비어있을 경우 이것을 이용한다. - 명령형
'queryClient.prefetchQuery'를 이용해 데이터를 미리 받는다.
'queryClient.setQueryData'를 사용하는 캐시에 수동적으로 데이터를 삽입한다.
선언형 Initial Query Data
Initial Data Function
초기데이터가 무겁거나(느린 API를 사용하거나, 대용량 데이터베이스에서 데이터를 읽어오는 경우), 렌더링할때마다 초기값을 넘겨주길 원치않는다면 'initialData'의 value로 메서드를 넘겨주면 된다. 메서드를 vlaue로 사용할 경우 쿼리가 초기화되는 단 한번반 'initialData'를 사용한다. 이렇게 사용할 경우 메모리 및 CPU비용을 절약할 수 있다.
const result = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/todos'),
initialData: () => getExpensiveTodos(),
})
Initial Data from Cache
다른 cach값으로 생성된 데이터를 초기데이터로 사용할수도 있다.
아래의 예시에서는 'todos'라는 query key를 탐색하여 cach된 데이터를 찾은뒤 이것을 초기데이터로 활용하고 있다.
const result = useQuery({
queryKey: ['todo', todoId],
queryFn: () => fetch('/todos'),
initialData: () => {
// Use a todo from the 'todos' query as the initial data for this todo query
return queryClient.getQueryData(['todos'])?.find((d) => d.id === todoId)
},
})
Initial Data from cache with 'initialDataUpdateAt'
'initialData'를 캐시로부터 가져오는 것은 쿼리가 이미 오래되었다는 것을 어느정도 전제로 한다. initialData를 사용하는 것이 아닌 staleTime을 인위적으로 설정하여 쿼리가 즉시 다시 가져오는 것을 막는 대신, initialDataUpdatedAt에 원래의 쿼리에서 dataUpdatedAt을 전달하는 것이 좋습니다. 이렇게 하면 쿼리 인스턴스가 가져와야 할 데이터가 있는지 언제 가져와야 하는지를 결정하는 데 필요한 모든 정보가 제공되므로, 초기 데이터가 제공되는지 여부와 관계없이 쿼리를 다시 가져와야 하는지를 결정할 수 있습니다.
const result = useQuery({
queryKey: ['todos', todoId],
queryFn: () => fetch(`/todos/${todoId}`),
initialData: () =>
queryClient.getQueryData(['todos'])?.find((d) => d.id === todoId),
initialDataUpdatedAt: () =>
queryClient.getQueryState(['todos'])?.dataUpdatedAt,
})
Conditional Initial Data from Cache
If the source query you're using to look up the initial data from is old, you may not want to use the cached data at all and just fetch from the server. To make this decision easier, you can use the queryClient.getQueryState method instead to get more information about the source query, including a state.dataUpdatedAt timestamp you can use to decide if the query is "fresh" enough for your needs:
const result = useQuery({
queryKey: ['todo', todoId],
queryFn: () => fetch(`/todos/${todoId}`),
initialData: () => {
// Get the query state
const state = queryClient.getQueryState(['todos'])
// If the query exists and has data that is no older than 10 seconds...
if (state && Date.now() - state.dataUpdatedAt <= 10 * 1000) {
// return the individual todo
return state.data.find((d) => d.id === todoId)
}
// Otherwise, return undefined and let it fetch from a hard loading state!
},
})
Further reading
For a comparison between Initial Data and Placeholder Data, have a look at the Community Resources.
'React-Query' 카테고리의 다른 글
Guides&Concepts_(Mutation) (0) | 2023.04.24 |
---|---|
Guides&Concepts_(Placeholder Query Data & Prefetching) (0) | 2023.04.24 |
Guides&Concepts_(Infinite Queries) (0) | 2023.04.23 |
Guides&Concepts_(Query Retries & Paginated Queries) (0) | 2023.04.22 |
Guides&Concepts_(React Query with Next.js) (0) | 2023.03.28 |