-
Notifications
You must be signed in to change notification settings - Fork 1
Tanstack Query 사용법
Jimyu edited this page Jul 25, 2025
·
4 revisions
TanStack Query에서 queryKey는 쉽게 생각하면 "데이터의 이름표" 같은 개념!
TanStack Query는 서버에서 가져오는 데이터를 저장하고 관리한다.
이때 데이터가 여러 가지면 헷갈리기 때문에 각 데이터마다 이름표인 queryKey를 붙여서 구분하는 것!
예시
-
학생 목록 데이터 →
['students'] -
특정 학생 상세 정보(학생 ID가 5번인 경우) →
['student', 5]
이렇게 이름표가 다르면 TanStack Query가 캐시를 따로 관리해줘서 데이터 꼬임 없이 사용 가능
-
데이터 주제(엔티티) 중심으로 만들기
- 예:
users,posts,comments등
- 예:
-
필요하면 세부 조건 추가
- 예: 특정 ID, 필터 값, 페이지 번호 등
-
배열 형태로 구조화
- TanStack Query는 배열을 쓰는 걸 권장해.
예:
['posts', postId],['comments', { postId, page: 2 }]
- TanStack Query는 배열을 쓰는 걸 권장해.
예:
// An individual todo
useQuery({ queryKey: ['todo', 5], ... })
// An individual todo in a "preview" format
useQuery({ queryKey: ['todo', 5, { preview: true }], ...})
// A list of todos that are "done"
useQuery({ queryKey: ['todos', { type: 'done' }], ... })
// QueryKey.ts
export const QUERY_KEYS = {
// 기본 리스트
STUDENTS: ['students'] as const,
POSTS: ['posts'] as const,
// 세부 항목 (함수로 ID 넘겨주기)
studentDetail: (id: number) => ['student', id] as const,
postDetail: (id: number) => ['post', id] as const,
// 조건 있는 경우
comments: (postId: number, page: number) =>
['comments', { postId, page }] as const,
};import { useQuery } from '@tanstack/vue-query'
import { QUERY_KEYS } from './QueryKey'
// 학생 목록 불러오기
const { data: students } = useQuery({
queryKey: QUERY_KEYS.STUDENTS,
queryFn: fetchStudents,
})
// 특정 학생 불러오기
const { data: studentDetail } = useQuery({
queryKey: QUERY_KEYS.studentDetail(5),
queryFn: () => fetchStudentDetail(5),
})- queryKey = 데이터 이름표
- 배열 형태로 만들고, 조건(아이디나 페이지) 있으면 두 번째 요소로 추가
- 한 파일에 모아서 관리하면 유지보수가 편해짐
-
useQuery→ GET 전용 (데이터 불러오기) -
useMutation→ POST/PUT/PATCH/DELETE (데이터 변경) - 변경 후
invalidateQueries로 캐시 무효화 하면 목록 자동 갱신 가능 - Mutation은 수동 실행(예: 버튼 클릭 시)으로 트리거
- QueryKey로 통일된 키 사용 → 캐시 충돌 방지 & 유지보수 편리
역할
- 서버에서 데이터 가져올 때 사용
- 컴포넌트 로드 시 자동 실행
- 결과를 자동으로 캐싱(저장) 하고, 리페치(새로고침) 도 편하게 해줌
- 주로 목록 조회, 상세 조회 같은 읽기 전용 요청에 사용
import { useQuery } from '@tanstack/vue-query'
import axios from 'axios'
const fetchStudents = async () => {
const { data } = await axios.get('/api/students')
return data
}
// 쿼리 훅
const { data, isLoading, error } = useQuery({
queryKey: ['students'], // 캐싱용 이름표
queryFn: fetchStudents, // 실제 데이터 가져오는 함수
staleTime: 1000 * 60, // 1분 동안은 신선한 데이터로 취급(지나면 갱신)
})역할
- 서버에 데이터를 추가, 수정, 삭제할 때 사용(즉, 데이터에 변경이 일어날 때)
- 결과를 캐시하지 않는다 → 대신 성공 후 직접 쿼리 무효화(invalidate)나 리페치(refetch) 해줘야 함
- 주로 폼 제출, 수정 버튼 클릭 같은 동작에 사용
import { useMutation, useQueryClient } from '@tanstack/vue-query'
import axios from 'axios'
const addStudent = async (newStudent: { name: string }) => {
const { data } = await axios.post('/api/students', newStudent)
return data
}
// mutation 훅
const queryClient = useQueryClient()
const { mutate, isPending } = useMutation({
mutationFn: addStudent, // POST 요청 실행
onSuccess: () => {
// 성공하면 students 쿼리 새로고침
queryClient.invalidateQueries({ queryKey: ['students'] })
},
})사용할 때
<button @click="mutate({ name: '홍길동' })">학생 추가</button>const queryClient = useQueryClient()
const { data: students } = useQuery({ queryKey: ['students'], queryFn: fetchStudents })
const { mutate: addStudent } = useMutation({
mutationFn: (newStudent) => axios.post('/api/students', newStudent),
onSuccess: () => {
// 학생 추가 후 목록 다시 불러오기
queryClient.invalidateQueries({ queryKey: ['students'] })
},
})