React Query는 모든 re-render에 대해 queryFn을 호출하지 않으며, 기본적인 유효 기간(0초)이 지나도 마찬가지이다.
refetchOnWindowFocus 속성
쿼리가 fresh 상태에서 stale 상태로 전환될 때까지 걸리는 유효 기간
fresh 상태이면 데이터를 캐시에서 가져오기 때문에 네트워크 요청이 발생하지 않는다.
stale 상태이면 여전히 데이터를 캐시에서 가져오지만, 특정 상황에서는 백그라운드에서 re-fetch가 발생할 수 있다.
비활성 쿼리가 캐시에서 제거될 때까지 걸리는 기간으로 기본값은 5분이다.
쿼리는 등록된 옵저버가 없는 즉시 비활성 상태로 전환된다.
cacheTime을 조작할 일은 거의 없다.
DevTools를 통해 캐시에 존재하는 데이터를 확인할 수 있다.
const fetchTodos = async state => {
const response = await axios.get(`todos/${state}`)
return response.data
}
export const useTodosQuery = state =>
useQuery(['todos', state], () => fetchTodos(state))
keepPreviousData
옵션을 사용하거나 initialData
속성을 사용한다.export const useTodosQuery = state =>
useQuery(['todos', state], () => fetchTodos(state), {
initialData: () => {
const allTodos = queryClient.getQueryData(['todos', 'all'])
const filteredData =
allTodos?.filter((todo) => todo.state === state) ?? []
return filteredData.length > 0 ? filteredData : undefined
},
})
queryFn은 사용자가 Promise를 반환할 것으로 예상하고, 결과 데이터는 쿼리 캐시로 전환된다.
서버에서 제공하는 구조의 데이터를 그대로 반환할 필요는 없고 변환할 수 있다.
const fetchTodos = async () => {
const response = await axios.get('todos')
const data: Todos = response.data
return data.map((todo) => todo.name.toUpperCase())
}
export const useTodosQuery = () => useQuery(['todos'], fetchTodos)
useMemo
를 통해 최적화할 수 있다.queryInfo
자체를 종속성으로 추가하면 변환이 모든 렌더에서 실행된다.export const useTodosQuery = () => {
const queryInfo = useQuery(['todos'], fetchTodos)
return {
...queryInfo,
data: React.useMemo(
() => queryInfo.data?.map((todo) => todo.name.toUpperCase()),
[queryInfo.data]
),
}
}
export const useTodosQuery = () =>
useQuery(['todos'], fetchTodos, {
select: (data) => data.map((todo) => todo.name.toUpperCase()),
})
const transformTodoNames = todos =>
data.map((todo) => todo.name.toUpperCase())
export const useTodosQuery = () =>
useQuery(['todos'], fetchTodos, {
select: transformTodoNames,
})
export const useTodosQuery = () =>
useQuery(['todos'], fetchTodos, {
select: React.useCallback(
data => data.map((todo) => todo.name.toUpperCase()),
[]
),
})
export const useTodosQuery = select =>
useQuery(['todos'], fetchTodos, { select })
export const useTodosCount = () => useTodosQuery(data => data.length)
export const useTodo = id =>
useTodosQuery(data => data.find(todo => todo.id === id))
stale 상태일 때 데이터를 캐시에서 가져오는 건 처음 알았어요 ! 유익한 글 감사합니다 ~~