TanStack Query 핵심 개념
기본 쿼리 사용법
const { data, isLoading, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
staleTime: 5 * 60 * 1000,
cacheTime: 30 * 60 * 1000
});
주요 상태값들
- isLoading: 첫 로딩 시 데이터를 가져오는 중
- isFetching: 데이터를 가져오는 중 (백그라운드 리페칭 포함)
- isError: 에러 발생 여부
- isSuccess: 데이터 로드 성공 여부
Query Key
- Query Key는 데이터를 식별하는 고유한 키입니다:
useQuery({ queryKey: ['todos'], queryFn: fetchTodos })
useQuery({
queryKey: ['todo', todoId],
queryFn: () => fetchTodoById(todoId)
})
useQuery({
queryKey: ['todos', { status, sort }],
queryFn: () => fetchTodosByStatus(status, sort)
})
데이터 변경: Mutations
const mutation = useMutation({
mutationFn: (newTodo) => axios.post('/todos', newTodo),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
onError: (error) => {
}
});
mutation.mutate(newTodo);
유용한 옵션들
const { data } = useQuery({
queryKey: ['todo', todoId],
queryFn: () => fetchTodoById(todoId),
enabled: !!todoId
});
const { data } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
select: (data) => data.filter(todo => todo.completed)
});
- refetchInterval: 주기적인 데이터 갱신
const { data } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
refetchInterval: 1000 * 60
});
캐시 관리
queryClient.invalidateQueries({ queryKey: ['todos'] });
queryClient.setQueryData(['todos'], (old) => [...old, newTodo]);
Infinite Queries
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage
} = useInfiniteQuery({
queryKey: ['projects'],
queryFn: fetchProjectPage,
getNextPageParam: (lastPage) => lastPage.nextCursor
});
주요 장점
- 서버 상태 관리 최적화
- 개발자 경험
- 직관적인 API
- TypeScript 지원
- DevTools 제공
- 성능 최적화
- 자동 가비지 컬렉션
- 메모리 관리
- 요청 중복 제거