Library/TanStack Query

[ TanStack Query ] TanStack Query (React Query)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

ma.caron_g 2025. 2. 24. 16:58

์ฐธ๊ณ ์‚ฌ์ดํŠธ

Transtack Query ๊ณต์‹ ๋ฌธ์„œ

 

TanStack Start Overview | TanStack Start React Docs

TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using tools like and . It is ready to deploy...

tanstack.com

HEROPY.DEV ๋‹˜์˜ ๋ธ”๋กœ๊ทธ

 

TanStack Query(React Query) ํ•ต์‹ฌ ์ •๋ฆฌ

TanStack Query๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ๋ฐ์ดํ„ฐ ์บ์‹ฑ, ์บ์‹œ ์ œ์–ด ๋“ฑ ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, React Query๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, v4๋ถ€ํ„ฐ Vue๋‚˜ Svelte ๋“ฑ์˜ ๋‹ค๋ฅธ

www.heropy.dev

 

๐ŸŒดTanStack Query

Tanstack Query(์ด์ „ React Query)๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ๋ฐ์ดํ„ฐ ์บ์‹ฑ, ์ œ์–ด ๋“ฑ ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ณ  ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

 

๊ธฐ์กด์—๋Š” React Query๋ผ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์ดํ›„ Vue, Solid, Svelete ๋“ฑ ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋„ ์‚ฌ์šฉํ•˜๋ฉด์„œ React๋ฅผ ์ œ์™ธํ•˜๊ณ  ๊ฐœ๋ฐœ์ž๋ช…์„ ๋”ฐ์™€ Tanstack Query๋กœ ์ด๋ฆ„์„ ๋ณ€๊ฒฝ.

 

๊ณต์‹ ๋ฌธ์„œ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค.

์›น ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ๋†’์€ ํ€„๋ฆฌํ‹ฐ์˜ ์˜คํ”ˆ์†Œ์Šค.

 

๊ฐ•๋ ฅํ•œ ๋น„๋™๊ธฐ ์ƒํƒœ๊ด€๋ฆฌ ๋„๊ตฌ

๐Ÿ’ช๐Ÿป ๋Œ€ํ‘œ ๊ธฐ๋Šฅ

โœ… ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์บ์‹ฑ

โœ… ๋™์ผ ์š”์ฒญ์˜ ์ค‘๋ณต ์ œ๊ฑฐ

โœ…  ์‹ ์„ ํ•œ ๋ฐ์ดํ„ฐ ์œ ์ง€

โœ…  ๋ฌดํ•œ ์Šคํฌ๋กค, ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋“ฑ์˜ ์„ฑ๋Šฅ ์ตœ์ ํ™”

โœ…  ๋„คํŠธ์›Œํฌ ์žฌ์—ฐ๊ฒฐ ์š”์ฒญ, ์‹คํŒจ ๋“ฑ์˜ ์ž๋™ ๊ฐฑ์‹ 

 

 

๐Ÿ“ฆ ๋ฐ์ดํ„ฐ ์บ์‹ฑ

TanStack Query๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ํ•ญ์ƒ ์ฟผ๋ฆฌ ํ‚ค (Query-Key)๋ฅผ ์ง€์ •ํ•˜๊ฒŒ ๋œ๋‹ค.

์ด ์ฟผ๋ฆฌ-ํ‚ค๋Š” ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ์™€ ๋น„๊ตํ•ด ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ์ง€, ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€์ด ๋œ๋‹ค.

 

Query-key๋ฅผ ํ†ตํ•ด ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ, ์บ์‹ฑ์— ํ•ด๋‹น ํ‚ค๋กœ ์ ‘๊ทผํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„, ์—†๋‹ค๋ฉด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์บ์‹ฑํ•œ๋‹ค.

 

๊ทธ ์ดํ›„, ์ฟผ๋ฆฌ ํ‚ค๋กœ ์ผ์น˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ, ์„œ๋ฒ„์— ์š”์ฒญํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

์ด๋ ‡๋‹ค๋ฉด ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์š”์ฒญ์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐœ์ƒํ•ด๋„, ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์–ด ์ค‘๋ณต ์š”์ฒญ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

 

โœจ ๋ฐ์ดํ„ฐ์˜ ์‹ ์„ ๋„

TanStack Query๋Š” ์บ์‹œํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ ์„ (Fresh)ํ•˜๊ฑฐ๋‚˜ ์ƒํ•œ(Stale) ์ƒํƒœ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ด€๋ฆฌํ•œ๋‹ค.

์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‹ ์„ ํ•˜๋‹ค๋ฉด ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒํ–ˆ๋‹ค๋ฉด ์„œ๋ฒ„์— ๋‹ค์‹œ ์š”์ฒญํ•ด ์‹ ์„ ํ•œ(์ƒˆ๋กœ์šด) ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

์ผ์ข…์˜ ๋ฐ์ดํ„ฐ ์œ ํ†ต๊ธฐํ•œ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค.

 

๋ฐ์ดํ„ฐ๊ฐ€ ์ƒํ•˜๋Š”๋ฐ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ staleTime ์˜ต์…˜์„ ํ†ตํ•ด ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์‹ ์„ ํ•œ์ง€ ์—ฌ๋ถ€๋Š” isStale๋กœ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

"use client"

import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function Home() {
  return (
    <QueryClientProvider client={queryClient}>
      <StaleData/>
    </QueryClientProvider>
  )
}

function StaleData() {
  const { data, isStale } = useQuery({
    queryKey: ['todo'],
    queryFn: async () => (await fetch('https://jsonplaceholder.typicode.com/todos/1')).json(),
    staleTime: 1000 * 3,
  })
  return <div className='flex flex-col items-center justify-center h-screen bg-gray-900 text-white'>
  <div>๋ฐ์ดํ„ฐ {isStale ? '๐Ÿ›์‹ ์„ ํ•˜์ง€ ์•Š์Œ' : '๐ŸŽ์‹ ์„ ํ•จ'}</div>
  <div>{JSON.stringify(data)}</div>
  </div>
}

 

ํ•ด๋‹น ์ฝ”๋“œ๋Š” Stale์„ 3์ดˆ๋กœ ์ง€์ •ํ–ˆ๋‹ค. 

๋ Œ๋”๋ง ํ›„, 3์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉด 3์ดˆ ํ›„์— ์‚ฌ๊ณผ๊ฐ€ ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

(์™ผ) ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜จ ํ›„ ์‹ ์„ ํ•œ ํ™”๋ฉด / (์šฐ) ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ณ  3์ดˆ ํ›„ ์ƒํ•œ ํ™”๋ฉด

 

 

๐Ÿš€ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

TanStack Query๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์•ž์„œ, ํ”„๋กœ์ ํŠธ ๋ฒ”์œ„๋ฅผ <QueryClientProvider>๋กœ ๋žฉํ•‘ํ•ด์•ผํ•œ๋‹ค.

import {
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'
import Children from '~/components/Children'

const queryClient = new QueryClient()

export default function Home() {
  return (
    <QueryClientProvider client={queryClient}>
      <Children/>
    </QueryClientProvider>
  )
}

๐Ÿ’ช๐Ÿป useQuery

๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ฟผ๋ฆฌ ํ›…์œผ๋กœ, ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

const result = useQuery<T>(option)

 

option์—๋Š” ๊ฐ์ฒดํ˜•์œผ๋กœ ๋งŽ์€ ์˜ต์…˜๋“ค์ด ์กด์žฌํ•˜๋Š”๋ฐ ์•„๋ž˜ ๋งํฌ์—์„œ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

@TanStack-Query/useQuery#Options

 

useQuery | TanStack Query React Docs

tsx const { data, dataUpdatedAt, error, errorUpdatedAt, failureCount, failureReason, fetchStatus, isError, isFetched, isFetchedAfterMount, isFetching, isInitialLoading, isLoading, isLoadingError, isPa...

tanstack.com

 

 

๐Ÿ’ช๐Ÿป QueryKey

์ฟผ๋ฆฌ ํ‚ค(query key)๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๊ณ ์œ ํ•œ ๊ฐ’์œผ๋กœ, ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ง€์ •ํ•œ๋‹ค.

๋‹ค์ค‘ ์•„์ดํ…œ ์ฟผ๋ฆฌ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š”, ์•„์ดํ…œ์˜ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค.

// ๋‹จ์ผ ์•„์ดํ…œ ์ฟผ๋ฆฌ ํ‚ค
useQuery({ queryKey: ['hello'] })

// ๋‹ค์ค‘ ์•„์ดํ…œ ์ฟผ๋ฆฌ ํ‚ค
useQuery({ queryKey: ['hello', 'world', 123, { a: 1, b: 2 }] })

// ์„œ๋กœ ๊ฐ™์€ ์ฟผ๋ฆฌ
useQuery({ queryKey: ['hello', 'world', 123, { a: 1, b: 2 }] })
useQuery({ queryKey: ['hello', 'world', 123, { b: 2, c: undefined, a: 1 }] })

// ์„œ๋กœ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ
useQuery({ queryKey: ['hello', 'world', 123, { a: 1, b: 2 }] })
useQuery({ queryKey: ['hello', 'world', 123, { a: 1, b: 2, c: 3 }] })
useQuery({ queryKey: ['hello', 'world'] })
useQuery({ queryKey: [123, 'world', { a: 1, b: 2, c: 3 }, 'hello'] })

 

ํ˜„์‹œ์  ์ž‘์„ฑ์ž ๋ถ„์„

โœ… ๋‹จ์ผ ์•„์ดํ…œ: ์ฟผ๋ฆฌ ํ‚ค ๋ฐฐ์—ด์— ํ•˜๋‚˜์˜ ํ‚ค๊ฐ€ ์กด์žฌํ•  ๋•Œ,

โœ… ๋‹ค์ค‘ ์•„์ดํ…œ: ์ฟผ๋ฆฌ ํ‚ค ๋ฐฐ์—ด์— ์—ฌ๋Ÿฌ ํ‚ค๊ฐ€ ์กด์žฌํ•  ๋•Œ,

โœ… ์„œ๋กœ ๊ฐ™์€ ์ฟผ๋ฆฌ: ๋ฐฐ์—ด ์ˆœ์„œ๊ฐ€ ๊ฐ™๊ณ , ๊ฐ์ฒด๋Š” ์ˆœ์„œ์™€ ์ƒ๊ด€์—†์ด ํ‚ค์Œ์ด ๋งž์„ ๋•Œ, (undefined๋Š” ์ œ์™ธ)

โœ… ์„œ๋กœ ๋‹ค๋ฅธ ์ฟผ๋ฆฌ: ๋ฐฐ์—ด ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๊ณ , ๊ฐ์ฒด๋Š” ์ˆœ์„œ ์ƒ๊ด€ ์—†์ง€๋งŒ ํ‚ค์Œ์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ

 

"use client"

import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function App() {
  
  return (
    <div className='flex flex-col items-center justify-center h-screen bg-gray-900 text-white'>
      <QueryClientProvider client={queryClient}>
        <TanstackComponent id={1} />
        <TanstackComponent id={2} />
      </QueryClientProvider>
    </div>
  )
}


type JsonPlaceholder = {
  userId: number
  id: number
  title: string
  completed: boolean
}

type TanstackComponentProps = {
  id?: number
}

function TanstackComponent({id}: TanstackComponentProps) {
  const { data, isStale } = useQuery<JsonPlaceholder>({
    queryKey: ['delay', id],
    queryFn: async () => {
      return (await fetch(`https://jsonplaceholder.typicode.com/todos${id ? `/${id}` : ''}`)).json();
    },
    staleTime: 1000 * 3,
  })

  return (
  <div className='flex flex-col items-center justify-center'>    
    <div>๋ฐ์ดํ„ฐ {isStale ? '๐Ÿ›์‹ ์„ ํ•˜์ง€ ์•Š์Œ' : '๐ŸŽ์‹ ์„ ํ•จ'}</div>
    <div>{JSON.stringify(data)}</div>
  </div>
  );
}

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด jsonplaceholder ์—์„œ ToDo ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ, id๋ฅผ ๋™์ ์œผ๋กœ ์ ์šฉํ•˜์—ฌ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ์„ ๋•Œ, ์ฟผ๋ฆฌ ํ‚ค์— id๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 

 

๐Ÿ’ช๐ŸปqueryFn

์ฟผ๋ฆฌ ํ•จ์ˆ˜(queryFn)๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋А ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ, ๊ผญ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๋ฅผ ๋˜์ ธ์•ผ ํ•œ๋‹ค.

๋˜์ ธ์ง„ ์˜ค๋ฅ˜๋Š” ๋ฐ˜ํ™˜๋˜๋Š” error ๊ฐ์ฒด๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

error๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ null ์ด๋‹ค.

 

API ์š”์ฒญ ๋„์ค‘, ์—๋Ÿฌ๋ฅผ ๋˜์ ธ์„œ useQuery()๋กœ ์—๋Ÿฌ๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉํ•œ๋‹ค.

 

์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

"use client"

import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function App() {
  
  return (
    <div className='flex flex-col items-center justify-center h-screen bg-gray-900 text-white'>
      <QueryClientProvider client={queryClient}>
        <TanstackComponent id={1}/>
        <TanstackComponent id={2}/>
      </QueryClientProvider>
    </div>
  )
}

type JsonPlaceholder = {
  userId: number
  id: number
  title: string
  completed: boolean
}

type TanstackComponentProps = {
  id?: number
}

function TanstackComponent({id}: TanstackComponentProps) {
  const { data, isStale, isPending, error } = useQuery<JsonPlaceholder>({
    queryKey: ['delay', id],
    queryFn: async () => {      
      const result = await fetch(`https://jsonplaceholder.typicode.com/todos${id ? `/${id}` : ''}/์˜ค๋ฅ˜๋ฐœ์ƒ`);
      const data = await result.json();
      if(data.id !== 3) {
        throw new Error('์—๋Ÿฌ ๋ฐœ์ƒ');
      }
      return data;

    },
    staleTime: 1000 * 3,
    retry: false,
  })

  if(isPending) {
    return <div className='text-green-400 p-3'>๐ŸŸข ๋กœ๋”ฉ์ค‘...</div>
  }

  if(error) {
    return <div className='text-red-500 p-3 font-bold'>โš ๏ธ ์—๋Ÿฌ ๋ฐœ์ƒ</div>
  }
  
  return (
  <div className='flex flex-col items-center justify-center'>    
    <div>๋ฐ์ดํ„ฐ {isStale ? '๐Ÿ›์‹ ์„ ํ•˜์ง€ ์•Š์Œ' : '๐ŸŽ์‹ ์„ ํ•จ'}</div>
    <div>{JSON.stringify(data)}</div>
  </div>
  );
}

 

์ขŒ) ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ธฐ ์ „ Pending ์ƒํƒœ / ์šฐ) ๋ฐ์ดํ„ฐ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ

 

๐Ÿ’ช๐Ÿปselect

์„ ํƒ ํ•จ์ˆ˜(select)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ˜•(์„ ํƒ) ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฟผ๋ฆฌ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ ์„ ํƒ ํ•จ์ˆ˜์—์„œ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ตœ์ข… ๋ฐ์ดํ„ฐ๊ฐ€ ๋œ๋‹ค.

์ตœ์ข… ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ useQuery์˜ 3๋ฒˆ์งธ ์ œ๋„ค๋ฆญ ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

"use client"

import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from '@tanstack/react-query'

const queryClient = new QueryClient()

export default function App() {
  
  return (
    <div className='flex flex-col items-center justify-center h-screen bg-gray-900 text-white'>
      <QueryClientProvider client={queryClient}>
        <TanstackComponent id={1}/>
        <TanstackComponent id={2}/>
      </QueryClientProvider>
    </div>
  )
}

type JsonPlaceholder = {
  userId: number
  id: number
  title: string
  completed: boolean
}

type TanstackComponentProps = {
  id?: number
}

type returnType = {
  [key: string] : number
}

function TanstackComponent({id}: TanstackComponentProps) {
  const { data, isStale, isPending, error } = useQuery<JsonPlaceholder, Error, returnType>({
    queryKey: ['delay', id],
    queryFn: async () => {  
      const result = await fetch(`https://jsonplaceholder.typicode.com/todos${id ? `/${id}` : ''}`);
      const data = await result.json();
      if(!data.id) {
        throw new Error('์—๋Ÿฌ ๋ฐœ์ƒ');
      }
      return data;

    },
    staleTime: 1000 * 3,
    select: data => ({ id: data.id }),
  })

  if(isPending) {
    return <div className='text-green-400 p-3'>๐ŸŸข ๋กœ๋”ฉ์ค‘...</div>
  }

  if(error) {
    return <div className='text-red-500 p-3 font-bold'>โš ๏ธ ์—๋Ÿฌ ๋ฐœ์ƒ</div>
  }
  
  return (
  <div className='flex flex-col items-center justify-center'>    
    <div>๋ฐ์ดํ„ฐ {isStale ? '๐Ÿ›์‹ ์„ ํ•˜์ง€ ์•Š์Œ' : '๐ŸŽ์‹ ์„ ํ•จ'}</div>
    <div>{JSON.stringify(data)}</div>
  </div>
  );
}

 

useQuery()์— ๋ฐ˜ํ™˜ ๋˜๋Š” ํƒ€์ž…๋“ค์„ ์ ์–ด์ฃผ๊ณ  ์„ธ ๋ฒˆ์งธ๋Š” ์ตœ์ข… ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€ ๋’ค

select๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋“ฌ์–ด ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

๋‚˜๋Š” id๊ฐ’๋งŒ ๊ฐ€์ ธ์™€๋ดค๋‹ค.