[TECH-QA] createQueryKeys

createQueryKeys

createQueryKeys๋Š” TanStack Query (React Query)์˜ ๊ณต์‹ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ, ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋งŒ๋“  ์ธ๊ธฐ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ @lukemorales/query-key-factory ํŒจํ‚ค์ง€์˜ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ๊ณผ ๋ชฉ์ 

์ด ํ•จ์ˆ˜๋Š” ํƒ€์ž… ์„ธ์ดํ”„(Type-safe)ํ•˜๊ณ  ๊ตฌ์กฐํ™”๋œ Query Key Factory๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. TanStack Query์—์„œ queryKey๋ฅผ ์ง์ ‘ ๋ฐฐ์—ด๋กœ ๊ด€๋ฆฌํ•˜๋‹ค ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋์–ด์š”.
  • ํ‚ค ์˜คํƒ€ ๋ฐœ์ƒ
  • invalidateQueries ํ•  ๋•Œ ํ‚ค๋ฅผ ์ž˜๋ชป ๊ธฐ์–ต
  • ํƒ€์ž… ์ถ”๋ก ์ด ์•ฝํ•จ
  • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ํ‚ค ๊ด€๋ฆฌ ์–ด๋ ค์›€
import { createQueryKeys } from '@lukemorales/query-key-factory';

export const taskQueries = createQueryKeys('task', {
  // ๊ธฐ๋ณธ ํ‚ค (parent key)
  all: null, // _def: ['task']

  // ์ƒ์„ธ ์กฐํšŒ
  detail: (taskId: string) => ({
    queryKey: [taskId], // ์‹ค์ œ ํ‚ค: ['task', 'detail', taskId]
    // queryFn๋„ ๊ฐ™์ด ์ •์˜ ๊ฐ€๋Šฅ
    // queryFn: () => fetchTask(taskId),
  }),

  // ๋ฆฌ์ŠคํŠธ
  list: (filters?: TaskFilters) => ({
    queryKey: filters ? [{ filters }] : [],
  }),
});
createQueryKeys ์—์„œ task ์ด๊ฒƒ์ด ๋ถ€๋ชจํ‚ค์ด๊ณ  , ๋‚˜๋จธ์ง€ ์•„๋ž˜ detail, list ๋“ฑ๋“ฑ createQueryKeys ์•ˆ์— ๋ชจ๋“  api ํ†ต์‹  ์‚ฌ์šฉ ํ‚ค๊ฐ€ ์กด์žฌ ํ•ฉ๋‹ˆ๋‹ค. ๋ถ€๋ชจํ‚ค๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋ฉด ํ•˜์œ„ ์ฟผ๋ฆฌ๊ฐ€ ๋‹ค ์—…๋ฐ์ดํŠธ ๋ฉ๋‹ˆ๋‹ค. createQueryKeys๋ฅผ ์“ฐ๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ ๋ถ€๋ชจ ํ‚ค(parent key)๋งŒ ๋ฌดํšจํ™”(invalidate)ํ•˜๋ฉด ๊ทธ ์•„๋ž˜ ๋ชจ๋“  ํ•˜์œ„ ์ฟผ๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ ๋ฆฌํŒจ์น˜(refetch)๋˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ „์ฒด ๊ณต์ง€ ๊ด€๋ จ ๋ถ€๋ชจ ํ‚ค

all: null, // _def: ['task']
noticeQueries.detail('123') 
// โ†’ { queryKey: ['task', 'detail', '123'] }

noticeQueries.all 
// โ†’ { _def: ['task'] }  // invalidateํ•  ๋•Œ ๋ถ€๋ชจ ํ‚ค๋กœ ์œ ์šฉ

queryClient.invalidateQueries({
  queryKey: noticeQueries.all._def, // ['task'] ์ „์ฒด ๋ฌดํšจํ™”
});
// ๋˜๋Š” ๋ถ€๋ถ„ ๋ฌดํšจํ™”
queryClient.invalidateQueries({
  queryKey: noticeQueries.detail()._def, // ['task', 'detail']
});