๐Ÿ“ก 02. [์•„ํ‚คํ…์ฒ˜] ํšจ๊ณผ์ ์ธ Query Key ์„ค๊ณ„ ์›Œํฌ์ƒต

2026๋…„ 3์›” 4์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

์ „์—ญ ์บ์‹œ๋ฅผ ํŒŒํŽธํ™” ์—†์ด ๊ณ„์ธต์ ์œผ๋กœ ์„ค๊ณ„ํ•˜๋Š” ๊ธฐ๋ฒ•๊ณผ, ์‹ค๋ฌด์˜ ๊ฝƒ์ธ Query Key Factory ํŒจํ„ด(๋ฐ Query Options API)์„ ๋„์ž…ํ•˜์—ฌ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ํ™•๋ณดํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ

"์˜์ฒ  ๋‹˜, ์•„๊นŒ invalidateQueries(['todos']) ์น˜์…จ์ฃ ? ๋ฐฉ๊ธˆ ์˜์ˆ™ ๋‹˜์ด ๋ณด๋Š” ํ™”๋ฉด ์บ์‹œ๊นŒ์ง€ ์‹น ๋‚ ์•„๊ฐ”์Šต๋‹ˆ๋‹ค. ์ฟผ๋ฆฌ ํ‚ค ์˜คํƒ€ ๋‚ด์…จ๊ฑฐ๋“ ์š”."

โ˜•๏ธ ์˜์ฒ ์ด์˜ ๊ณ ๋ฏผ: "๋ฌดํšจํ™”๋ฅผ ๋‚ ๋ ธ๋Š”๋ฐ ์—‰๋šฑํ•œ ์• ๋“ค์ด ์‚ฌ๋ผ์ ธ์š”..."

(ํ™”์š”์ผ ์ ์‹ฌ ์ง์ „, ๋ฒ„๊ทธ ์ œ๋ณด๋ฅผ ๋ฐ›๊ณ  ์ฐฝ๋ฐฑํ•ด์ง„ ์˜์ฒ )

๐Ÿฃ ์˜์ฒ : ์•„ ๋ฆฌ๋“œ ๋‹˜ ํฐ์ผ ๋‚ฌ์–ด์š”! ์œ ์ €๊ฐ€ '์™„๋ฃŒ๋œ ํ•  ์ผ' ๋ชฉ๋ก์—์„œ ์•„์ดํ…œ ํ•˜๋‚˜ ์‚ญ์ œํ–ˆ๋Š”๋ฐ, ๊ฐ‘์ž๊ธฐ ๋ฉ”์ธ ํ™”๋ฉด์— ์žˆ๋˜ '์ง„ํ–‰ ์ค‘์ธ ํ•  ์ผ' ๋ฆฌ์ŠคํŠธ๋ž‘ '์ด๋ฒˆ ๋‹ฌ ์ „์ฒด ํ†ต๊ณ„' ์บ์‹œ๊นŒ์ง€ ๋ชฝ๋•… ํญํŒŒ(Invalidate)๋ผ์„œ ์ „๋ถ€ ๋ฏธ์นœ ๋“ฏ์ด ๋ฆฌํŒจ์นญ ์น˜๊ณ  ์„œ๋ฒ„ ๋ถ€ํ•˜๊ฐ€ ํŠ€์—ˆ์–ด์š”;;

๐Ÿฆ ์˜ํ˜ธ: ์ฝ”๋“œ ์ค˜ ๋ณด์„ธ์š”. (ํƒ€๋‹ฅํƒ€๋‹ฅ)
queryClient.invalidateQueries({ queryKey: ['todos'] }) ์ด๋ ‡๊ฒŒ ์˜์…จ๊ตฐ์š”.
์˜์ฒ  ๋‹˜์ด ๋ชจ๋“  ํ›…๋“ค์— ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ['todos', 'done'], ['todos', 'in-progress'], ์‹ฌ์ง€์–ด ['todos', 'stats', 'monthly'] ์ด๋ ‡๊ฒŒ ์ค‘๊ตฌ๋‚œ๋ฐฉ ๋ฌธ์ž์—ด๋กœ ๋‹ฌ์•„๋‘์…จ์ž–์•„์š”.
React Query์˜ invalidate ๋Š” ์ƒ์œ„ ํ‚ค(['todos']) ๋งŒ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๊ทธ ๋ฐ‘์˜ ๊ผฌ๋ฆฌํ‘œ๊ฐ€ ๋‹ฌ๋ฆฐ ํ•˜์œ„ ํŠธ๋ฆฌ ์ „์ฒด๋ฅผ ์ž๋น„ ์—†์ด ๋ฐ•์‚ด ๋‚ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ : ํ—‰! ๊ทธ๋Ÿผ ์ง€์šฐ๊ณ  ์‹ถ์€ '์™„๋ฃŒ๋œ ๋ฆฌ์ŠคํŠธ'๋งŒ ๋”ฑ ๊ผฌ์ง‘์–ด์„œ ์ง€์šฐ๋ ค๋ฉด ์–ด๋–กํ•ด์š”?

๐Ÿฆ ์˜ํ˜ธ: ๊ทธ๋ž˜์„œ 5๋…„ ์ฐจ ์‹ค๋ฌด์˜ ์‹œ์ž‘์€ "์ฟผ๋ฆฌ ํ‚ค ํŒฉํ† ๋ฆฌ(Query Key Factory)" ๊ณ„์ธตํ˜• ์•„ํ‚คํ…์ฒ˜ ๋ฅผ ์งœ๋Š” ๊ฒƒ๋ถ€ํ„ฐ ์ถœ๋ฐœํ•˜๋Š” ๊ฒ๋‹ˆ๋‹ค. ์ค‘์•™ ํ†ต์ œ์†Œ๊ฐ€ ์—†์œผ๋ฉด ์ด๋Ÿฐ ์ŠคํŒŒ๊ฒŒํ‹ฐ ๋ฌดํšจํ™” ํ˜„์ƒ์ด ํ„ฐ์ง‘๋‹ˆ๋‹ค.


๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€: ๋ฌธ์ž์—ด ์˜คํƒ€๊ฐ€ ๋ถ€๋ฅด๋Š” ์บ์‹œ ๋Œ€์ฐธ์‚ฌ

React Query์˜ ์ฝ”์–ด ์‹ฌ์žฅ์€ QueryCache ๋ผ๋Š” ๊ฑฐ๋Œ€ํ•œ ๊ธˆ๊ณ ์ž…๋‹ˆ๋‹ค.
๊ทธ ๊ธˆ๊ณ ์˜ ๋ฐฉ ๋ฒˆํ˜ธ๊ฐ€ ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ฐฐ์—ด๋กœ ๋„˜๊ฒจ์ฃผ๋Š” Query Key ์ฃ .

์—ฌ๊ธฐ์„œ ๋ฐœ์ƒํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์น˜๋ช…์  ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ํƒ€์ž…์˜ ๋ถ€์žฌ: ๊ฐœ๋ฐœ์ž A๋Š” useQuery({ queryKey: ['todo', 1] }) ๋ผ๊ณ  ์งœ๊ณ , ๊ฐœ๋ฐœ์ž B๋Š” ์‚ญ์ œ ์™„๋ฃŒ ํ›„ ์—‰๋šฑํ•˜๊ฒŒ queryClient.invalidateQueries({ queryKey: ['todos', 1] }) ๋ผ๊ณ  ์˜คํƒ€๋ฅผ ๋ƒ…๋‹ˆ๋‹ค. ์•„๋ฌด์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  ์œ ์ €๋Š” ์˜์›ํžˆ ๋‚ก์€ ํ™”๋ฉด์„ ๋ด…๋‹ˆ๋‹ค. (TypeScript๋„ ๋ฌธ์ž์—ด ์˜คํƒ€๋Š” ๋ชป ์žก์•„์ค๋‹ˆ๋‹ค!)
  2. ๋ถ€๋น„ํŠธ๋žฉ(Fuzzy Matching): ๋ฐฐ์—ด์˜ ํฌํ•จ ๊ด€๊ณ„ ์›๋ฆฌ๋ฅผ ๋ชจ๋ฅด๋ฉด, ์˜์ฒ ์ด์ฒ˜๋Ÿผ ์‹ค์ˆ˜๋กœ ์•ฑ ์ „์ฒด์˜ ๋„คํŠธ์›Œํฌ๋ฅผ ์ฃ„๋‹ค ์ดˆ๊ธฐํ™”์‹œ์ผœ๋ฒ„๋ฆฌ๋Š” ๋ฏธ์นœ ์„ฑ๋Šฅ ์ €ํ•˜ ํญ๋ฐœ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ์ฑ•ํ„ฐ์—์„œ๋Š” ์ „์—ญ ์ƒ์ˆ˜ ๊ฐ์ฒด ๋กœ ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ์„ค๊ณ„ํ•˜์—ฌ ํœด๋จผ ์—๋Ÿฌ๋ฅผ 0%๋กœ ๋ฐ•๋ฉธํ•˜๋Š” ์ตœ๊ฐ•์˜ ๊ตฌ์กฐ๋ฅผ ๋ฐฐ์›๋‹ˆ๋‹ค.


1. ๋ฐฐ์—ด ํ‚ค์˜ ํฌํ•จ ๊ด€๊ณ„ (Fuzzy Matching) ํ•ด๋ถ€

TkDodo์˜ ์•„ํ‹ฐํด #8์— ๋ช…์‹œ๋œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ฌดํšจํ™” ๋ฃฐ์ž…๋‹ˆ๋‹ค.
"์•ž์—์„œ๋ถ€ํ„ฐ ๊ณ„์ธต(๋ฐฐ์—ด ์ˆœ์„œ)์ด ์ผ์น˜ํ•˜๋ฉด ๋ฌด์กฐ๊ฑด ํƒ€๊ฒŸ ๋Œ€์ƒ์ด ๋œ๋‹ค!"

queryClient.invalidateQueries({ queryKey: ['todos'] }) ํ•˜๋‚˜๋ฅผ ๋ฐœ์‚ฌํ–ˆ์„ ๋•Œ,

  • โœ… ['todos'] (๋งž์Œ -> ๋ฌดํšจํ™”)
  • โœ… ['todos', 'list', 'done'] (todo๊ณ„์—ด ๋งž์Œ -> ๋ฌดํšจํ™” ๋ฒ”์œ„ ์•ˆ ๋จ!)
  • โœ… ['todos', 'detail', 1] (todo๊ณ„์—ด ๋งž์Œ -> ์‚ญ์ œ!)
  • โŒ ['users', 'todos'] (ํ‹€๋ฆผ, ๋งจ ์•ž์ด users์ž„ -> ์‚ด๋ ค์คŒ)

๋งŒ์•ฝ ์˜์ฒ ์ด๊ฐ€ "๋”ฑ 'done' ์ƒํƒœ์ธ ๋ฆฌ์ŠคํŠธ๋งŒ" ์šฐ์•„ํ•˜๊ฒŒ ์ง€์šฐ๊ณ  ์‹ถ์—ˆ๋‹ค๋ฉด?
๋ฐ˜๋“œ์‹œ ์ •ํ™•ํ•˜๊ฒŒ queryClient.invalidateQueries({ queryKey: ['todos', 'list', 'done'] }) ๊นŒ์ง€ ๊ตฌ์ฒด์ ์œผ๋กœ ์ง‘์–ด๋„ฃ์–ด์•ผ๋งŒ ๋‹ค๋ฅธ ํ˜•์ œ ์บ์‹œ๋“ค(['todos', 'detail', 1])์ด ํญํŒŒ๋˜๋Š” ๊ฑธ ์‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


2. ์‹ค์ „ ์ ์šฉ: Query Key Factory ์•„ํ‚คํ…์ฒ˜

๋ฌธ์ž์—ด ํ•˜๋“œ์ฝ”๋”ฉ์„ ์›์ฒœ ๋ด‰์‡„ํ•˜๊ธฐ ์œ„ํ•ด ์ „์—ญ ํŒฉํ† ๋ฆฌ ํŒŒ์ผ(keys.ts ๋˜๋Š” queries.ts)์— ์ƒ์ˆ˜ํ™”๋œ ๊ฐ์ฒด(Factory Pattern) ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

// ๐Ÿ“ constants/queryKeys.ts
 
// ๐Ÿš€ ๋ชจ๋“  ์ฟผ๋ฆฌ ํ‚ค๋Š” ์ด ๊ฐ์ฒด ํŠธ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ๋‹ค! (๊ณต์žฅ)
export const todoKeys = {
  // 1๋‹จ๊ณ„: ๊ธฐ๋ณธ ๋„๋ฉ”์ธ ํ‚ค (์ „์ฒด ๋ฌดํšจํ™” ๋•Œ ์“ธ ๊ฑฐ๋Œ€ํ•œ ํญํƒ„ ์Šค์œ„์น˜)
  all: ['todos'] as const,
  
  // 2๋‹จ๊ณ„: ๋ฆฌ์ŠคํŠธ ๊ณ„์—ด ๋ฌถ์Œ ํ‚ค
  lists: () => [...todoKeys.all, 'list'] as const,
  // 3๋‹จ๊ณ„: ๊ตฌ์ฒด์ ์ธ ๊ฒ€์ƒ‰/ํ•„ํ„ฐ ๋ฆฌ์ŠคํŠธ (์ƒ์œ„ ํ‚ค๋“ค์„ ์ „๋ถ€ ํ’ˆ๊ณ  ๋‚ด๋ ค์˜ด)
  list: (filters: string) => [...todoKeys.lists(), { filters }] as const,
  
  // 2๋‹จ๊ณ„: ๋‹จ๊ฑด(๋””ํ…Œ์ผ) ๊ณ„์—ด ๋ฌถ์Œ ํ‚ค
  details: () => [...todoKeys.all, 'detail'] as const,
  // 3๋‹จ๊ณ„: ํŠน์ • 1๊ฑด ๋””ํ…Œ์ผ
  detail: (id: number) => [...todoKeys.details(), id] as const,
};

์ด๋ ‡๊ฒŒ ๊ณต์žฅ์„ ์ฐจ๋ ค๋‘๋ฉด, ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ(View, Hook) ์ชฝ ์ฝ”๋“œ๊ฐ€ 100% ์•ˆ์ „ํ•˜๊ณ  ์˜คํƒ€ ์—†๋Š” ์ฝ”๋“œ๋กœ ์ง„ํ™”ํ•ฉ๋‹ˆ๋‹ค.

// 1๏ธโƒฃ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ฌ ๋•Œ
import { todoKeys } from '@/constants/queryKeys';
 
function TodoDetail({ id }: { id: number }) {
  // ์˜คํƒ€ ๋‚  ํ™•๋ฅ  0%, id ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์•ˆ ๋„ฃ์œผ๋ฉด TypeScript๊ฐ€ ์ฆ‰์‹œ ์—๋””ํ„ฐ์—์„œ ์—๋Ÿฌ ๋ฟœ์Œ!
  const { data } = useQuery({
    queryKey: todoKeys.detail(id), 
    queryFn: () => fetchTodoDetail(id),
  });
}
// 2๏ธโƒฃ ์‚ญ์ œ/์ˆ˜์ • ์™„๋ฃŒ ํ›„ ๋ฌดํšจํ™” ํ•  ๋•Œ (์ •๋ฐ€ ํƒ€๊ฒฉ)
const deleteMutation = useMutation({
  mutationFn: deleteTodo,
  onSuccess: () => {
    // ๐Ÿ”ฅ "todos ๋””ํ…Œ์ผ ์บ์‹œ๋Š” ๋‹ค ์‚ด๋ ค๋‘๊ณ , ๋ฆฌ์ŠคํŠธ ๊ณ„์—ด ๋ Œ๋”๋ง๋งŒ ์‹น ๋‹ค์‹œ ํ•ด!"
    queryClient.invalidateQueries({ queryKey: todoKeys.lists() });
  }
})

3. ๊ถ๊ทน์˜ Next Step: Query Options API (v5)

์•„ํ‚คํ…์ฒ˜์— ์š•์‹ฌ์ด ๋งŽ์€ ์‹œ๋‹ˆ์–ด๋“ค์€ ํ•œ ํ†ต ๋” ๋‚˜์•„๊ฐ‘๋‹ˆ๋‹ค.
ํ‚ค(queryKey) ๋”ฐ๋กœ, ํŽ‘์…˜(queryFn) ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค. ์–ด์ฐจํ”ผ ['todos', id] ๋ฉด ๋ฌด์กฐ๊ฑด fetchTodoDetail(id) ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋Š” ๊ฒŒ ํ•„์—ฐ์ ์ธ ์šด๋ช…(Coupling)์ด์ž–์•„์š”?

๊ทธ๋ž˜์„œ ์ตœ์‹  React Query v5 ์—์„œ๋Š” ์ด ๋‘˜์„ ํ•œ ๋ชธ์œผ๋กœ ๋ฌถ์–ด๋ฒ„๋ฆฐ queryOptions ๊ธฐ๋ฐ˜์˜ ํŒฉํ† ๋ฆฌ๊ฐ€ ํ‘œ์ค€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค (TkDodo #24 ์ฐธ์กฐ). ์•ž์„  Basic 07๊ฐ•์˜ ์‹ฌํ™” ๋ณต์Šต์ž…๋‹ˆ๋‹ค.

import { queryOptions } from '@tanstack/react-query';
 
export const todoQueries = {
  all: () => ['todos'],
  
  // ํ‚ค + ํŽ˜์นญ ๋กœ์ง + ๋งŒ๋ฃŒ๊ธฐ๊ฐ„(staleTime) ๊นŒ์ง€ ์˜์›ํžˆ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด๋ฒ„๋ฆผ!
  detail: (id: number) => queryOptions({
    queryKey: [...todoQueries.all(), 'detail', id],
    queryFn: () => axios.get(`/todos/${id}`).then(res => res.data as Todo),
    staleTime: 5 * 60 * 1000, 
  }),
};
// ๋ฐ์ดํ„ฐ ์ˆ˜์ • ๋ฌดํšจํ™” ๋•Œ, ๊ทธ๋ƒฅ ํ†ต์งœ ์˜ต์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐœ์‚ฌํ•ด ๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.
queryClient.invalidateQueries(todoQueries.detail(1));

๋‹จ ํ•œ ์ค„์˜ ๋ฌธ์ž์—ด ์˜คํƒ€(String Typo)๋„ ๋ฐœ์ƒ ๋ถˆ๊ฐ€๋Šฅํ•œ, ๋นˆํ‹ˆ์—†๋Š” ํ‹ฐํƒ€๋Š„ ์žฅ๋ฒฝ์ด ํ”„๋ก ํŠธ์—”๋“œ ์ „์ฒด์— ๊น”๋ฆฌ๊ฒŒ ๋˜๋Š” ์…ˆ์ด์ฃ !


๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

ํ—... todoKeys.all, todoKeys.lists() ์ด๋ ‡๊ฒŒ ๋ถ€๋ชจ ๋ฐฐ์—ด ๊ป๋ฐ๊ธฐ ๊ทธ๋Œ€๋กœ ํ™•์žฅ(...spread)ํ•ด์„œ ๊ฐ€์ ธ๋‹ค ๋ถ™์ด๋‹ˆ๊นŒ ๋ฌดํšจํ™”์‹œํ‚ฌ ๋•Œ ์Šค์ฝ”ํ”„(Scope) ๋”ฑ๋”ฑ ๋‚˜๋ˆ ์„œ ์ œ์–ดํ•˜๋Š” ๊ฑฐ ์˜ˆ์ˆ ์ด๋‹ค ์ง„์งœ.

๐Ÿ’ก ์˜ค๋Š˜์˜ ๊ตํ›ˆ: "ํ•˜๋“œ์ฝ”๋”ฉ ๋ฐฐ์—ด ['foo', 'bar'] ์„ ์“ฐ๋Š” ์ž๋Š” ์—๋Ÿฌ ์ˆ˜์Šต์— ๋ฐค์„ ์ƒˆ์šฐ๋ฆฌ๋ผ! ๋ฌด์กฐ๊ฑด ๊ฐ์ฒด ๊ธฐ๋ฐ˜์˜ Query Key Factory ํŒจํ„ด(๋˜๋Š” Query Options ํŒฉํ† ๋ฆฌ)์„ ๊ตฌ์ถ•ํ•ด์„œ ํŒŒ์ผ ํ•˜๋‚˜์— ๋ชจ๋“  ์บ์‹œ ๊ธˆ๊ณ  ์ด๋ฆ„์„ ํ†ต์ œํ•˜์ž."

์•„๊นŒ ์˜คํƒ€ ๋‚˜์„œ ์ „์ฒด ๋ฌดํšจํ™” ์ณค์„ ๋•Œ ์˜์ˆ˜(๋ฐฑ์—”๋“œ) ๋‹˜ ๋ชจ๋‹ˆํ„ฐ์— ํ„ฐ์ ธ๋‚˜์˜ค๋˜ ์„œ๋ฒ„ ๋ถ€ํ•˜ ํŠธ๋ž˜ํ”ฝ ๋กœ๊ทธ๊ฐ€ ์•„์ง๋„ ๋ˆˆ์•ž์— ์„ ํ•˜๋‹ค ใ…‹ใ…‹ ใ… ใ… ... ๋‚ด์ผ ์ผ์ฐ ์ถœ๊ทผํ•ด์„œ ์•ฑ ๊ณณ๊ณณ์— ์˜คํƒ€ ํ™•๋ฅ  ์ˆจ์–ด์žˆ๋Š” [] ๋ฆฌํ„ฐ๋Ÿด ํ‚ค๋“ค ์‹น ๋‹ค ์ฐพ์•„์„œ queryOptions ์ œ๊ตญ์œผ๋กœ ๋Œ€ํ†ต์ผ ์‹œ์ผœ๋†”์•ผ์ง€!!


๐Ÿ“ ๋ฐฐ์šด ๋‚ด์šฉ ์ ๊ฒ€ํ•˜๊ธฐ (Quiz)

Q. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณ„์ธต์„ ๊ฐ€์ง€๋Š” ์ฟผ๋ฆฌ ํ‚ค ํŒฉํ† ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • Mutation ์ดํ›„์— ์•„๋ž˜์˜ invalidateQueries ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ, ๋ฌดํšจํ™”(์‚ญ์ œ ๋ฐ ๋ฆฌํŒจ์น˜ ๋งˆํ‚น)๋ฅผ 'ํ”ผํ•˜๊ฒŒ ๋˜๋Š”(์ƒ์กดํ•˜๋Š”)' ์บ์‹œ๋Š” ์–ด๋А ๊ฒƒ์ผ๊นŒ์š”?

queryClient.invalidateQueries({ queryKey: ['orders', 'shipping'] });
  • A) ['orders', 'shipping', 'list', { status: 'done' }]
  • B) ['orders', 'shipping', 12345]
  • C) ['orders', 'payment', 'list']

โœ… ์ •๋‹ต: C

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: React Query์˜ ๋ฌดํšจํ™”(invalidate) ๋‚ด๋ถ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ "๋ฐฐ์—ด์˜ ์•ž์—์„œ๋ถ€ํ„ฐ ๊ฐ’์ด ์™„๋ฒฝํžˆ ์ผ์น˜ํ•˜๋Š”(ํฌํ•จ ๊ด€๊ณ„์ธ) ๋ชจ๋“  ํ•˜์œ„ ๋…ธ๋“œ๋ฅผ ํญํŒŒ" ์‹œํ‚ค๋Š” ํผ์ง€ ๋งค์นญ(Fuzzy Matching)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ž…๋ ฅํ•œ ์˜์Šค๋Š” ['orders', 'shipping'] ์ด๋ฏ€๋กœ, ์•ž ๋‘ ์ž๋ฆฌ๊ฐ€ ์ € ๊ธ€์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” A๋ฒˆ๊ณผ B๋ฒˆ์˜ ๋ฌด์ˆ˜ํžˆ ๋งŽ์€ ์ƒ์„ธ ํŠธ๋ฆฌ ๊ฐ€์ง€๋“ค์€ ๋ชจ์กฐ๋ฆฌ ํญํŒŒ๋ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, C๋ฒˆ ์บ์‹œ๋Š” orders ๊นŒ์ง€๋Š” ๊ฐ™์ง€๋งŒ ๋‘ ๋ฒˆ์งธ ๊ณ„์ธต์—์„œ shipping์ด ์•„๋‹ˆ๋ผ payment๋กœ ๊ฐˆ๋ผ์กŒ์ฃ ? ๊ทธ๋ž˜์„œ ๋ฐฉํญ ํ…ํŠธ ์•ˆ์— ์•ˆ์ „ํ•˜๊ฒŒ ์‚ด์•„๋‚จ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ณ„์ธต(Hierarchy) ์ˆœ์„œ ์„ค๊ณ„๊ฐ€ ๋ฌดํšจํ™”์˜ ํญ๋ฐœ ๋ฐ˜๊ฒฝ(Blast Radius)์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒ๋‹ˆ๋‹ค!"
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ์•ž์—์„œ๋ถ€ํ„ฐ ์ŠคํŽ ๋ง&์ˆœ์„œ ์ผ์น˜ = ํฌํ•จ๋œ ๋ชจ๋“  ์ž์‹ ๋ฐ•์‚ด. ์—‡๋‚˜๊ฐ„ ๊ฐ€์ง€ = ์ƒ์กด!