๐Ÿ“ก 07. ์ปค์Šคํ…€ ํ›…(Custom Hooks)์œผ๋กœ Query ์ถ”์ƒํ™”ํ•˜๊ธฐ

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

๐Ÿ“‹ ๊ฐœ์š”

์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์‚ฐ์žฌํ•œ useQuery ๋กœ์ง์„ ์ปค์Šคํ…€ ํ›…๊ณผ queryOptions API๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ๊ทน๋Œ€ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ

"์˜์ฒ  ๋‹˜, ๋˜‘๊ฐ™์€ useQuery ์„ค์ •์„ ์ปดํฌ๋„ŒํŠธ 5๊ตฐ๋ฐ์— ๋‹ค ๋ณต๋ถ™ํ•ด ๋†“์œผ์…จ๋„ค์š”. ๋‚˜์ค‘์— API ์ฃผ์†Œ ๋ฐ”๋€Œ๋ฉด 5๊ตฐ๋ฐ ๋‹ค ์ฐพ์•„์„œ ๊ณ ์น˜์‹ค ๊ฑด๊ฐ€์š”?"

โ˜•๏ธ ์˜์ฒ ์ด์˜ ๊ณ ๋ฏผ: "์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๊ณ  ๋šฑ๋šฑํ•ด์š”!"

(์ˆ˜์š”์ผ ์˜คํ›„, ์ฝ”๋“œ๋ฅผ ์Šคํฌ๋กคํ•˜๋‹ค ์†๊ฐ€๋ฝ์— ์ฅ๊ฐ€ ๋‚œ ์˜์ฒ )

๐Ÿฃ ์˜์ฒ : ์•„ ๋ฆฌ๋“œ ๋‹˜... ์ €ํฌ ์ปค๋ฎค๋‹ˆํ‹ฐ ์•ฑ ์—ฌ๊ธฐ์ €๊ธฐ์„œ '์ธ๊ธฐ ๊ฒŒ์‹œ๊ธ€' ๋ชฉ๋ก์„ ๋„์›Œ์•ผ ํ•˜๊ฑฐ๋“ ์š”? ๊ทธ๋ž˜์„œ ๋ฉ”์ธ ํŽ˜์ด์ง€, ๋งˆ์ด ํŽ˜์ด์ง€, ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€๋งˆ๋‹ค useQuery ์จ์„œ ์ฟผ๋ฆฌ ํ‚ค ๋„ฃ๊ณ , queryFn ๋„ฃ๊ณ , staleTime 5๋ถ„์œผ๋กœ ๋งž์ถ”๊ณ ... ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๊ณ„์† ์น˜๋‹ค ๋ณด๋‹ˆ๊นŒ ํŒŒ์ผ ํ•˜๋‚˜๋‹น ์ฝ”๋“œ๊ฐ€ ๋ง‰ 200์ค„์”ฉ ๋„˜์–ด๊ฐ€์š” ใ… ใ… 

๐Ÿฆ ์˜ํ˜ธ: ์˜์ฒ  ๋‹˜, UI๋ฅผ ๊ทธ๋ฆฌ๋Š” ์ปดํฌ๋„ŒํŠธ(View) ์•ˆ์— ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ(Logic)์„ ์ƒ์œผ๋กœ ๋•Œ๋ ค ๋ฐ•์œผ๋‹ˆ๊นŒ ๋šฑ๋šฑํ•ด์ง€๋Š” ๊ฒ๋‹ˆ๋‹ค. React Query์˜ ๋ชจ๋“  ํ˜ธ์ถœ์€ ๋ฌด์กฐ๊ฑด ์ปค์Šคํ…€ ํ›…(Custom Hooks) ์œผ๋กœ ์ถ”์ƒํ™”ํ•ด์„œ ๋นผ๋‚ด๋Š” ๊ฒƒ์ด 5๋…„ ์ฐจ ์‹ค๋ฌด์˜ ๊ตญ๋ฃฐ์ž…๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ TypeScript ํƒ€์ž… ์ถ”๋ก ๊นŒ์ง€ ์–น์œผ๋ฉด ์™„๋ฒฝํ•ด์ง€์ฃ .


๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ๊ฒฉ๋ฆฌ

๋งŒ์•ฝ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์›์‹œ์ ์ธ useQuery๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ์ƒ๊น๋‹ˆ๋‹ค.

  1. ์ค‘๋ณต์˜ ์ €์ฃผ: ์ฟผ๋ฆฌ ํ‚ค ๋ฌธ์ž์—ด ์˜คํƒ€, staleTime ์„ค์ • ๋ˆ„๋ฝ ๋“ฑ ์—ฌ๊ธฐ์ €๊ธฐ์„œ ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ํ„ฐ์ง‘๋‹ˆ๋‹ค.
  2. ํƒ€์ž…์˜ ๋Šช: ์„œ๋ฒ„์—์„œ ๋‚ด๋ ค์˜ค๋Š” Response ํƒ€์ž…์„ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค ๋งค๋ฒˆ ์ œ๋„ค๋ฆญ(<T>)์œผ๋กœ ๋‹ฌ์•„์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ฐ€๋…์„ฑ ํŒŒ๊ดด: UI ๋ Œ๋”๋ง ์ฝ”๋“œ๋ณด๋‹ค ๋น„๋™๊ธฐ ์ƒํƒœ ๋ฝ‘์•„๋‚ด๋Š” ์ฝ”๋“œ๊ฐ€ ๋” ๊ธธ์–ด์ง‘๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ์šฐ๋ฆฌ๋Š” ์ฟผ๋ฆฌ ํ˜ธ์ถœ๋ถ€๋ฅผ useTodos, useUser ๊ฐ™์€ ์ปค์Šคํ…€ ํ›…์œผ๋กœ ์˜ˆ์˜๊ฒŒ ํฌ์žฅํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๊ฐ€ "์–ด๋–ป๊ฒŒ(How) ๊ฐ€์ ธ์˜ค๋Š”์ง€ ์•Œ ํ•„์š” ์—†์ด, ๋ฌด์—‡(What)๋งŒ ์“ฐ๋„๋ก" ์™„๋ฒฝํžˆ ๊ฒฉ๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


1. ์ปค์Šคํ…€ ํ›… ์ถ”์ƒํ™”์˜ 3๋‹จ๊ณ„ ์„ค๊ณ„

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ปค์Šคํ…€ ํ›… ๋ถ„๋ฆฌ ๋ฐฉ์‹์„ TypeScript ๊ทœ๊ฒฉ์— ๋งž์ถฐ ์‚ดํŽด๋ด…์‹œ๋‹ค.

โŒ ๋‹จ๊ณ„ 0: ๋šฑ๋šฑํ•œ ์ปดํฌ๋„ŒํŠธ (Before)

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
 
// ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ๊ฑธ ์•Œ๊ณ  ์žˆ๋‹ค!
function Dashboard() {
  const { data, isLoading } = useQuery<Todo[], Error>({
    queryKey: ['todos', 'done'],
    queryFn: async () => {
      const res = await axios.get('/todos?status=done');
      return res.data;
    },
    staleTime: 5 * 60 * 1000, // 5๋ถ„
  });
 
  return <div>...</div>;
}

โœ… ๋‹จ๊ณ„ 1: ํ›…์œผ๋กœ ๋ถ„๋ฆฌ (After)

์ƒˆ๋กœ์šด ํŒŒ์ผ hooks/queries/useTodos.ts ๋ฅผ ๋งŒ๋“ค๊ณ  ๋กœ์ง์„ ๋ชฝ๋•… ๋ชฐ์•„๋„ฃ์Šต๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ๋Š” ์˜ค์ง ์ด ํ›…๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

// ๐Ÿ“ hooks/queries/useTodos.ts
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
 
// 1. DTO ํƒ€์ž… ์„ ์–ธ (์ด ํŒŒ์ผ ์•ˆ์—์„œ๋งŒ ์‘์ง‘๋„ ๋†’๊ฒŒ ๊ด€๋ฆฌ)
export type Todo = { id: number; title: string; status: 'open' | 'done' };
 
// 2. ์ˆœ์ˆ˜ ํŽ˜์นญ ํ•จ์ˆ˜ (์ถ”ํ›„ ํ…Œ์ŠคํŒ…์ด๋‚˜ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ์žฌ์‚ฌ์šฉ ์šฉ์ด)
const fetchTodos = async (status: string): Promise<Todo[]> => {
  const { data } = await axios.get(`/todos?status=${status}`);
  return data;
};
 
// 3. โœจ ๋“œ๋””์–ด ์ปค์Šคํ…€ ํ›… (ํƒ€์ž… ์ถ”๋ก ์ด ์™„๋ฒฝํ•˜๊ฒŒ ํ˜๋Ÿฌ๊ฐ)
export const useTodos = (status: string) => {
  return useQuery({
    queryKey: ['todos', status],
    queryFn: () => fetchTodos(status),
    staleTime: 5 * 60 * 1000,
  });
};
// ๐ŸŽจ View ์ปดํฌ๋„ŒํŠธ๋Š” ๊ทน๋„๋กœ ๊ฐ€๋ฒผ์›Œ์ง„๋‹ค!
import { useTodos } from '@/hooks/queries/useTodos';
 
function Dashboard() {
  // Query Key๊ฐ€ ๋ญ”์ง€, staleTime์ด ์–ผ๋งŒ์ง€ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ชจ๋ฅธ๋‹ค. ๊ทธ์ € ๊บผ๋‚ด ์“ธ ๋ฟ!
  const { data: todos, isLoading } = useTodos('done');
  
  return <div>...</div>;
}

2. ์ง„ํ™”์˜ ๋: queryOptions API (v5์˜ ๋น„๊ธฐ)

๐Ÿฃ ์˜์ฒ : ์˜ค, ์ฝ”๋“œ๊ฐ€ ์ง„์งœ ๋ฐ˜ํ† ๋ง‰ ๋‚ฌ๋„ค์š”! ๊ทผ๋ฐ ๋ฆฌ๋“œ ๋‹˜, ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR)์ด๋‚˜ ํ”„๋ฆฌํŽ˜์นญ(Prefetching) ํ•  ๋•Œ ์„œ๋ฒ„ ์ฝ”๋“œ์—์„œ useQuery ํ›…์„ ๋ชฌ ์“ธ ํ…๋ฐ, ๊ทธ๋Ÿผ ๊ทธ๋• ์ฟผ๋ฆฌ ํ‚ค(['todos', status])๋ฅผ ๋˜ ์ƒ์œผ๋กœ ๋ฌธ์ž์—ด ์ณ์•ผ ํ•˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€์š”?

๐Ÿฆ ์˜ํ˜ธ: ํ•ต์‹ฌ์„ ์ฐ”๋ €๊ตฐ์š”! ํ›… ๋‚ด๋ถ€๋กœ ํ‚ค๋ฅผ ์™„์ „ํžˆ ์ˆจ๊ฒจ๋ฒ„๋ฆฌ๋ฉด ์ปดํฌ๋„ŒํŠธ ๋ฐ–(๋ฃจํ„ฐ ์ถฉ๋Œ, SSR ํ”„๋ฆฌํŽ˜์นญ, QueryCache ์ง์ ‘ ์ œ์–ด)์—์„œ ๊ทธ ํ‚ค์— ์ ‘๊ทผํ•˜๊ธฐ ํž˜๋“ค์–ด์ง‘๋‹ˆ๋‹ค. ์ด๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด React Query v5์—์„œ ์ถœ์‹œ๋œ queryOptions ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์จ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

queryOptions๋Š” ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  '์˜ต์…˜ ๋ฉ์–ด๋ฆฌ(๊ฐ์ฒด)' ๋งŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜ ์ž…๋‹ˆ๋‹ค.

// ๐Ÿ“ queries/todoOptions.ts
import { queryOptions } from '@tanstack/react-query';
 
// ๐Ÿš€ Option ํŒฉํ† ๋ฆฌ ์ƒ์„ฑ (ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์™„์ „ ์ง€์›)
export const todoOptions = {
  all: () => queryOptions({
    queryKey: ['todos'],
    queryFn: () => axios.get('/todos').then(res => res.data as Todo[]),
  }),
  detail: (status: string) => queryOptions({
    queryKey: ['todos', status],
    queryFn: () => axios.get(`/todos?status=${status}`).then(res => res.data as Todo[]),
    staleTime: 5 * 60 * 1000,
  }),
};

์ด ์˜ต์…˜ ๊ฐ์ฒด๊ฐ€ ์žˆ์œผ๋ฉด ํด๋ผ์ด์–ธํŠธ ํ›… ์ด๋“ , ์„œ๋ฒ„ ๋ผ์šฐํ„ฐ ๋“  ์–ธ์ œ ์–ด๋””์„œ๋‚˜ ๋ ˆ๊ณ  ๋ธ”๋ก์ฒ˜๋Ÿผ ๋ผ์›Œ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

// 1๏ธโƒฃ ์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ(Client)์—์„œ ์“ธ ๋•Œ
function Dashboard() {
  // Option ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ useQuery์— ์ „๊ฐœํ•ด์„œ ์ง‘์–ด๋„ฃ์Œ
  const { data } = useQuery(todoOptions.detail('done'));
}
 
// 2๏ธโƒฃ ๋กœ๋”(SSR API)๋‚˜ ์„œ๋ฒ„ ์•ก์…˜์—์„œ ํ”„๋ฆฌํŽ˜์นญ ํ•  ๋•Œ
async function prefetchDashboard() {
  const queryClient = new QueryClient();
  // ๋™์ผํ•œ ์˜ต์…˜ ๊ฐ์ฒด ์žฌ์‚ฌ์šฉ! ํ‚ค ์˜คํƒ€๊ฐ€ ๋‚  ํ™•๋ฅ  0%
  await queryClient.prefetchQuery(todoOptions.detail('done'));
}

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

์™€... ๋‚˜ ์˜ค๋Š˜ useTodos ํŒŒ์ผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด๋†“๊ณ  queryOptions ์•ˆ์—์„œ ๊น”์•„๋‘” ๋‹ค์Œ, ๋งˆ์ดํŽ˜์ด์ง€๋ž‘ ๋Œ€์‹œ๋ณด๋“œ์—์„œ useQuery(todoOptions.xxx()) ๋กœ ์ซ™ ๊ฐˆ์•„๋ผ์› ๋‹ค.
์ฝ”๋“œ ์ˆ˜๋ฐฑ ์ค„์ด ๊ทธ๋ƒฅ ์ฆ๋ฐœํ•˜๋Š” ๋งˆ์ˆ ;;

๐Ÿ’ก ์˜ค๋Š˜์˜ ๊ตํ›ˆ: "UI ํŒŒ์ผ ์•ˆ์—์„œ ์ง์ ‘ useQuery ํŒจํ„ด์„ ๋ฌด๋ฐฉ๋น„ํ•˜๊ฒŒ ๋ณต๋ถ™ํ•˜๋Š” ๊ฑด ์•ˆํ‹ฐํŒจํ„ด์ด๋‹ค. ์ฟผ๋ฆฌ ํ‚ค์™€ ํŽ˜์นญ ๋กœ์ง์€ ์ปค์Šคํ…€ ํ›…์ด๋‚˜ queryOptions ๊ฐ์ฒด๋กœ ์™„๋ฒฝํžˆ ๊ฒฉ๋ฆฌํ•ด์„œ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ '๋ฐ์ดํ„ฐ ์ค˜'๋ผ๊ณ  ์†Œ๋ฆฌ๋งŒ ์น˜๊ฒŒ ๋งŒ๋“ค์ž!"

๊ทธ๋ฆฌ๊ณ  TypeScript ์ผ์„ ๋•Œ ์ œ์ผ ์ข‹์€ ์ ! todoOptions.detail(123) ์น˜๋‹ˆ๊นŒ ๋นจ๊ฐ„ ์ค„ ๋œจ๋ฉด์„œ ์ƒํƒœ(status)๋Š” ๋ฌธ์ž์—ด์ด์•ผ, ๋ฐ”๋ณด์•ผ! ๋ผ๊ณ  ํ™”๋‚ด์ฃผ๋”๋ผ. ํœด... TS ์•ˆ ์ผ์œผ๋ฉด ๋ฐฑ์—”๋“œํ•œํ…Œ ์ˆซ์ž 123 ๋„˜๊ฒผ๋‹ค๊ฐ€ 400 ์—๋Ÿฌ ๋œจ๊ณ  ์–ด๋ฆฌ๋‘ฅ์ ˆํ•  ๋ป”. ์˜ค๋Š˜ ํ‡ด๊ทผ๊ธธ ๋ฐœ๊ฑธ์Œ ๊ฐœ๊ฐ€๋ณ๋‹ค ํซใ…Ž.


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

Q. ๊ธฐ์กด์—๋Š” ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ž‘์—…์„ ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ data.filter(...)๋‚˜ data.map(...)์œผ๋กœ ์ฒ˜๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ปค์Šคํ…€ ํ›…์„ ๋ถ„๋ฆฌํ•œ ์ดํ›„, ์›๋ณธ DB ๋ฐ์ดํ„ฐ๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ UI ์ž…๋ง›์— ๋งž๊ฒŒ ๊ฐ€๊ณต(Transformation)ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” React Query์˜ ๋‚ด์žฅ ์˜ต์…˜์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

  • A) queryFn ์•ˆ์—์„œ axios๋กœ ๋ฐ›์•„์˜จ ์งํ›„์— filter๋ฅผ ๋Œ๋ฆฐ๋‹ค.
  • B) ์ปค์Šคํ…€ ํ›… ๋‚ด๋ถ€์—์„œ useQuery ์„ค์ • ์ค‘ select ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๊ณตํ•œ๋‹ค.
  • C) ์ปค์Šคํ…€ ํ›…์—์„œ ๋ฐ˜ํ™˜ํ•œ data๋ฅผ, ์‚ฌ์šฉํ•  UI ์ปดํฌ๋„ŒํŠธ์—์„œ useMemo๋กœ ๋‹ค์‹œ ๊ฐ์‹ผ๋‹ค.

โœ… ์ •๋‹ต: B

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

  • ์›๋ฆฌ ์„ค๋ช…: TkDodo ์•„ํ‹ฐํด #2์— ๋”ฐ๋ฅด๋ฉด, React Query์˜ select ์˜ต์…˜์€ "์›๋ณธ ๋ฐ์ดํ„ฐ(์บ์‹œ)๋Š” ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ๋ƒ…๋‘” ์ฑ„, ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ๋…ํ•  ๋•Œ๋งŒ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์กฐ๊ฐ์œผ๋กœ ์ž˜๋ผ๋‚ด์–ด(Memozation) ๋˜์ ธ์ฃผ๋Š”" ์ตœ๊ฐ•์˜ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. select ์˜ต์…˜์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฒฐ๊ณผ๊ฐ’์„ ์บ์‹ฑํ•˜๋ฏ€๋กœ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ ๋‚ญ๋น„๋ฅผ ์™„๋ฒฝํžˆ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: "์˜์ฒ  ๋‹˜, A๋ฒˆ์ฒ˜๋Ÿผ queryFn ์•ˆ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐˆ์•„๋ฒ„๋ฆฌ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ๋‹ค๋ฅธ ํŽ˜์ด์ง€์—์„œ ์›๋ณธ ์ „์ฒด ๋ชฉ๋ก์„ ๋‹ฌ๋ผ๊ณ  ํ–ˆ์„ ๋•Œ ์บ์‹œํ†ต์—” ์ด๋ฏธ ๋‚œ๋„์งˆ๋‹นํ•œ ์กฐ๊ฐ๋ฐ–์— ์•ˆ ๋‚จ์•„์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค! C๋ฒˆ์ฒ˜๋Ÿผ ๋งค๋ฒˆ ๋ทฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์งŠ์–ด์ง€๊ฒŒ ํ•˜์ง€ ๋ง๊ณ , ๊น”๋”ํ•˜๊ฒŒ useQuery์˜ select์—๊ฒŒ ์œ„์ž„ํ•˜์„ธ์š”."
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: ์›๋ณธ ํ›ผ์† ์—†๋Š” ์šฐ์•„ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€๊ณต์€ ๋ฌด์กฐ๊ฑด select ์˜ต์…˜!