Tanstack Query 쿼리키 비교 방식

강연주·2025년 10월 9일

📚 TIL

목록 보기
176/186

쿼리키에 따른 데이터 페치 방식

  • 1단계: 인기순 선택
    queryKey: ["headhuntings", "like"]
    → API 호출 ✅
    → 캐시 저장: ["headhuntings", "like"] → 데이터A

  • 2단계: 서울 필터 추가
    queryKey: ["headhuntings", "like", "place", "서울"]
    → API 호출 ✅ (새로운 쿼리키이므로)
    → 캐시 저장: ["headhuntings", "like", "place", "서울"] → 데이터B

  • 3단계: 서울 필터 제거 (다시 인기순만)
    queryKey: ["headhuntings", "like"]
    → 🚀 API 호출 안함! 캐시에서 바로 가져옴
    → 캐시에서 읽기: ["headhuntings", "like"] → 데이터A (1단계 데이터)

  • 그럼 이 부분 다음에 가령, 4단계, headhuntings, like, place, 경기 라는 쿼리키로 호출한다면 이것은 데이터B에 경기 부분만 교체되는 거야? 아니면 새로운 데이터C를 전체 다 가져오는 거야?

  • ☀️ 답은, 새로운 데이터C를 전체 다 가져옵니다

단계별 분석

  • 1단계: 인기순
    queryKey: ["headhuntings", "like"]
    → API 호출 ✅
    → 캐시: ["headhuntings", "like"] → 데이터A (전체 100개)

  • 2단계: 서울 필터 추가
    queryKey: ["headhuntings", "like", "place", "서울"]
    → API 호출 ✅
    → 캐시: ["headhuntings", "like", "place", "서울"] → 데이터B (서울 30개)

  • 3단계: 서울 필터 제거
    queryKey: ["headhuntings", "like"]
    → 캐시에서 읽기 (API 호출 X)
    → 캐시: ["headhuntings", "like"] → 데이터A (전체 100개)

  • 4단계: 경기 필터 추가
    queryKey: ["headhuntings", "like", "place", "경기"]
    → 🌐 새로운 API 호출
    → 캐시: ["headhuntings", "like", "place", "경기"] → 데이터C (경기 25개)


TanStack Query의 캐시 키 비교 방식 (데이터B를 재활용하지 않는 이유)

쿼리키는 "문자열 전체"로 비교한다.

["headhuntings", "like", "place", "서울"]
  !== 
["headhuntings", "like", "place", "경기"]

// 즉, 완전히 다른 쿼리로 인식!

실제 캐시 저장소의 개념적 구조

const cache = {
  '["headhuntings","like"]': {
    data: [모임1, 모임2, ...모임100],  // 데이터A
  },
  '["headhuntings","like","place","서울"]': {
    data: [서울모임1, 서울모임2, ...서울모임30],  // 데이터B
  },
  '["headhuntings","like","place","경기"]': {
    data: [경기모임1, 경기모임2, ...경기모임25],  // 데이터C (새로 생성)
  },
};

실제 네트워크 요청 확인

  • 1단계: 인기순
    GET /api/v1/headhunting?sortBy=like&page=1&limit=10
    Response: 전체 데이터 (서울+경기+부산+...)

  • 2단계: 서울 필터
    GET /api/v1/headhunting?sortBy=like&place=서울&page=1&limit=10
    Response: 서울만 필터링된 데이터

  • 3단계: 필터 제거
    (네트워크 요청 없음 - 캐시 사용)

  • 4단계: 경기 필터
    GET /api/v1/headhunting?sortBy=like&place=경기&page=1&limit=10
    Response: 경기만 필터링된 새로운 데이터


부분 교체가 안 되는 이유

1. 백엔드에서 필터링되어 옴

typescript
// 서버 응답 구조
// 서울 필터 요청 시
{
  result: [
    { id: 1, place: "서울", ... },
    { id: 5, place: "서울", ... },
    { id: 8, place: "서울", ... },
  ],
  next: "..."
}

// 경기 필터 요청 시
{
  result: [
    { id: 2, place: "경기", ... },
    { id: 7, place: "경기", ... },
  ],
  next: "..."
}

서버가 이미 필터링해서 보내주기 때문에, 전체 데이터를 클라이언트가 갖고 있지 않다.

2. 쿼리키가 다르면 완전히 별개의 데이터

typescript
// 이런 식으로 동작하지 않습니다 ❌
const 데이터B = cache['["headhuntings","like","place","서울"]'];
const 데이터C = 데이터B.filter(item => item.place === "경기"); // ❌ 불가능!
// 왜? 데이터B에는 서울 데이터만 있고, 경기 데이터는 없으니까!

// 실제 동작 ✅
const 데이터C = await fetch(`/api?place=경기`); // 서버에서 새로 가져옴
profile
아무튼, 개발자

0개의 댓글