์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ React ํ™˜๊ฒฝ์—์„œ TanStack Query ์ฒซ ์‚ฌ์šฉ๊ธฐ

2023. 8. 30. 17:54ใ†react

๋ฐ˜์‘ํ˜•

์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์˜ React ํ™˜๊ฒฝ์—์„œ TanStack Query ์ฒซ ์‚ฌ์šฉ๊ธฐ

 

 

 

 

๋ถ€ํŠธ์บ ํ”„ ๋งˆ์ง€๋ง‰ ๊ณผ์ •์€ ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์˜€๋‹ค.

๊ธฐ๋ณธ์ ์ธ SNS ์„œ๋น„์Šค์— ๋Œ€ํ•œ API๋ฅผ ์ œ๊ณต๋ฐ›์€ ํ›„ ๋””์ž์ธ, ์•„ํ‚คํ…์ฒ˜, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ๊นŒ์ง€ ๋ชจ๋‘ ์ž์œ  ์ฃผ์ œ๋กœ ์ง„ํ–‰ํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์—์„œ TanStack Query๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋А๊ผˆ๋˜ ์–ด๋ ค์›€๊ณผ ์žฅ์ ๊ณผ ๋‹จ์  ๋“ฑ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž๋กœ์„œ ๊ฒช์—ˆ๋˜ ๊ฒฝํ—˜์„ ๊ธฐ๋กํ•ด ๋ณด๊ณ ์ž ํ•œ๋‹ค. ์šฐ์„  ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ธ useQuery์™€ useMutation์— ๋Œ€ํ•ด์„œ ์ž‘์„ฑํ•˜๊ณ , ์ฟผ๋ฆฌ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๊ธฐ์œ„ํ•œ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ๊ณผ, ๋ฌดํ•œ ์Šคํฌ๋กค, ์—๋Ÿฌ๋ฐ”์šด๋”๋ฆฌ์— ๋Œ€ํ•œ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์€ ์ด์–ด์„œ ์ž‘์„ฑํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

 

 1๏ธโƒฃ TanStack Query๋ž€?

 

TanStack Query ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€ ํ™”๋ฉด

TanStack Query๋Š” ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ์™€์˜ ๋™๊ธฐํ™” ๋ฐ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ž‘์—…์„ ํŽธํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ค„์—ฌ์ค€๋‹ค. ์ฃผ์š” ๊ธฐ๋Šฅ์œผ๋กœ๋Š” get, post, put ๋“ฑ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ์—…๋ฐ์ดํŠธ, ์บ์‹ฑ, ๋กœ๋”ฉ, ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์žˆ๋‹ค.

 

React Query๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋” ์œ ๋ช…ํ•œ TanStack Query๋Š” v3 ๊นŒ์ง€๋Š” React๋งŒ ์ง€์›ํ–ˆ๋Š”๋ฐ, v4๋ถ€ํ„ฐ React๋ฅผ ํฌํ•จํ•ด์„œ Vue, Svelte, Solid ์—์„œ๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง€๋ฉด์„œ TanStack Query๋กœ ์ด๋ฆ„์ด ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. ์—ฌ์ „ํžˆ TanStack Query๋ผ๋Š” ๋ช…์นญ๋ณด๋‹ค๋Š” React Query๋ผ๊ณ  ์ง€์นญ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

 

TanStack Query ์˜ ํ•ต์‹ฌ๊ธฐ๋Šฅ์œผ๋กœ๋Š” HTTP์˜ GET์š”์ฒญ๊ณผ ๊ฐ™์ด ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” useQuery ํ›…์ด ์žˆ๊ณ , POST, PUT, DELETE ์š”์ฒญ ๋“ฑ ๋ณ€์ด(์‚ฌ์ด๋“œ์ดํŽ™ํŠธ)๋ฅผ ์œ ๋ฐœํ•˜๋Š” useMutation ํ›…์ด ์žˆ๋‹ค. 

 

 

 

 2๏ธโƒฃ TanStack Query์˜ ์žฅ๋‹จ์ 

 

์žฅ์ 

  • ๋™์ผํ•œ ์š”์ฒญ์„ ๋™์‹œ์— ์—ฌ๋Ÿฌ๋ฒˆ ๋ณด๋‚ด๋„ ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ํ•œ ๋ฒˆ๋งŒ ๋ณด๋‚ด์„œ ๋ฉ”๋ชจ๋ฆฌ์— ์บ์‹œ ํ•˜๋ฏ€๋กœ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ํ›„์† ํ˜ธ์ถœ๋กœ ์ธํ•œ ์ค‘๋ณต ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„์„œ ํšจ์œจ์ ์ด๊ณ  ๊ฐ„ํŽธํ•˜๋‹ค.
  • ๋ฐ์ดํ„ฐ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด Refetch๊ฐ€ ์ผ์–ด๋‚˜๋Š” ์กฐ๊ฑด์„ ๋‹ค์–‘ํ•˜๊ฒŒ ์ œ๊ณตํ•œ๋‹ค. ์œˆ๋„์šฐ์— ํฌ์ปค์Šค(refetchOnWindowFocus)๋œ ๊ฒฝ์šฐ, ๋งˆ์šดํŠธ(refetchOnMount) ๋˜๋Š” ๊ฒฝ์šฐ, ์žฌ ์—ฐ๊ฒฐ(refetchOnReconnect)๋˜๋Š” ๊ฒฝ์šฐ ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๋Š” ๋กœ์ง์ด ์‹ฌํ”Œํ•ด์ง€๊ณ  ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ๊ฐ€ ์‹ ์†ํ•˜๊ฒŒ ๋ฐ˜์˜๋œ๋‹ค.
  • ํŽ˜์ด์ง€๋„ค์ด์…˜, ๋ฌดํ•œ ์Šคํฌ๋กค, ๋ฐ์ดํ„ฐ ์ง€์—ฐ ๋กœ๋”ฉ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”ํ•˜๊ธฐ ์ข‹๋‹ค.
  • Devtool์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์–ด์„œ ๋„คํŠธ์›Œํ‚น ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋””๋ฒ„๊น…์— ์šฉ์ดํ•˜๋‹ค.

 

๋‹จ์ 

  • ๊ตฌ๊ธ€๋ง, gpt(^^;)๋ฅผ ์ฐธ๊ณ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ์ค‘์ธ ๋ฒ„์ „๊ณผ ์ผ์น˜ํ•˜๋Š” ์ •๋ณด์ธ์ง€ ๊ผญ! ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์ž๋ฃŒ๊ฐ€ ์ด์ „ ๋ฒ„์ „ ์ž๋ฃŒ์ด๊ธฐ ๋•Œ๋ฌธ์— tanstack ๋ฒ„์ „์ธ์ง€ ๊ผญ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๊ณ , ๋˜๋„๋ก ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์•„์ง ๋ฆฌ๋•์Šค, ๋ฆฌ๋•์Šค ํˆดํ‚ท๋งŒํผ ๋ณดํŽธ์„ฑ์„ ๊ฐ–๊ณ ์žˆ์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋Œ€์ ์œผ๋กœ ์ฐธ๊ณ ํ• ๋งŒํ•œ ์ž๋ฃŒ๊ฐ€ ๋ถ€์กฑํ•œ ํŽธ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž์—๊ฒŒ๋Š” ๋ฆฌ๋•์Šค๋ณด๋‹ค ํ›จ์”ฌ ๋‹ค๋ฃจ๊ธฐ ์‰ฝ๊ธฐ ๋•Œ๋ฌธ์— ํ™œ์šฉํ•ด ๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

 

 

 

 3๏ธโƒฃ ์„ค์น˜ ๋ฐ ์ดˆ๊ธฐ ์„ธํŒ…

 

TanStack Query ์„ค์น˜

// npm
npm i @tanstack/react-query 

// yarn
$ yarn add react-query

 

app.js ์ดˆ๊ธฐ ์„ค์ •

  • QueryClientProvider ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ตœ์ƒ๋‹จ์— ๊ฐ์‹ธ๊ณ  QueryClient ์ธ์Šคํ„ด์Šค๋ฅผ client ์†์„ฑ์— ๋„ฃ์–ด์ค€๋‹ค.
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Example />
    </QueryClientProvider>
  )
}

 

 

 

4๏ธโƒฃ useQuery
  • GET์š”์ฒญ๊ณผ ๊ฐ™์€ CREAT์ž‘์—…์„ ํ• ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ›…์œผ๋กœ ์ฟผ๋ฆฌํ‚ค(queryKey)์™€ ์ฟผ๋ฆฌํ•จ์ˆ˜(queryFn)๋ฅผ ํ•„์ˆ˜๋กœ ์„ ์–ธํ•ด ์ค˜์•ผ ํ•œ๋‹ค. ์‘๋‹ต์€ data, ์—๋Ÿฌ๋Š” error, ์ฟผ๋ฆฌ ์ƒํƒœ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” status ๋“ฑ์„ ๋ฐ˜ํ™˜.
  • const requestData = useQuery(queryKey, queryFn, Option) ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ.
  • useQueries์™€ useInfiniteQuery ํ›…์€ useQuery์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ‘๋ ฌ๋กœ ๊ฐ€์ ธ์™€์•ผ ํ•  ๋•Œ๋Š” useQueries ํ›…์„, ๋ฌดํ•œ ์Šคํฌ๋กค๊ณผ ๊ฐ™์ด ๊ณ„์†ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•  ๊ฒฝ์šฐ useInfiniteQuery ํ›…์„ ์‚ฌ์šฉ.
  • ์ฟผ๋ฆฌํ‚ค(queryFn)๊ฐ€ ๋‹ค๋ฅด๋ฉด ํ˜ธ์ถœํ•˜๋Š” API๊ฐ€ ๋™์ผํ•ด๋„ ์บ์‹ฑ์„ ๋ณ„๋„๋กœ ๊ด€๋ฆฌํ•œ๋‹ค. Devtool์—์„œ๋„ ์ฟผ๋ฆฌํ‚ค๋ฅผ ์ธ์‹ํ•ด์„œ ๋””๋ฒ„๊น…ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์ค‘์š”!
function Example() {
  const { isLoading, error, data } = useQuery('repoData', () =>
    fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
      res.json()
    )
  )

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>๐Ÿ‘€ {data.subscribers_count}</strong>{' '}
      <strong>โœจ {data.stargazers_count}</strong>{' '}
      <strong>๐Ÿด {data.forks_count}</strong>
    </div>
  )
}

 

  • ๋ฐ์ดํ„ฐ ์š”์ฒญ
data status ==='success' ์„œ๋ฒ„ ์š”์ฒญ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ.
isLoading status === 'loading' ์ฟผ๋ฆฌ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉฐ ํ˜„์žฌ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘์ธ ์ƒํƒœ.
isError status === 'error' ์ฟผ๋ฆฌ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ.
isFetching true / false ์ฟผ๋ฆฌ์— ๋ฐ์ดํ„ฐ ์œ ๋ฌด์™€ ์ƒ๊ด€ ์—†์ด ํ˜„์žฌ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘์ธ ์ƒํƒœ.
error object ์„œ๋ฒ„ ์š”์ฒญ ์‹คํŒจ์— ๋Œ€ํ•œ ์‘๋‹ต.

 

  • ์˜ต์…˜
cacheTime unMount ์ดํ›„ ๋ฉ”๋ชจ๋ฆฌ์— ์–ธ์ œ๊นŒ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•ด์„œ ์บ์‹ฑํ•  ๊ฑด์ง€ ์„ค์ • ๊ธฐ๋ณธ 300000 (5๋ถ„)
staleTime stale(์‹ ์„ ํ•˜์ง€ ์•Š์€) ๋ฐ์ดํ„ฐ๋ฅผ ํŒจ์น˜ํ•ด์„œ ์–ธ์ œ ์ƒˆ๋กญ๊ฒŒ ๊ฐฑ์‹ ํ• ์ง€ ์„ค์ • ๊ธฐ๋ณธ 0
refetchOnMount ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ์‹œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ํŒจ์นญ ๊ธฐ๋ณธ true
refetchOnWindowFocus ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํฌ์ปค์Šค ๋  ๋•Œ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ํŒจ์น˜ ๊ธฐ๋ณธ true
refetchInterval ๋ธŒ๋ผ์šฐ์ €์— ํฌ์ปค์Šค๊ฐ€ ์žˆ์„ ๋•Œ ์ง€์ •ํ•œ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ๋งŒํผ ๋ฐ์ดํ„ฐ ํŒจ์นญ ๊ธฐ๋ณธ 0
refetchIntervalInBackground ๋ธŒ๋ผ์šฐ์ €์— ํฌ์ปค์Šค๊ฐ€ ์—†์–ด๋„ ์ง€์ •ํ•œ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ๋งŒํผ ๋ฐ์ดํ„ฐ ํŒจ์นญ ๊ธฐ๋ณธ false

 

๐Ÿ’กcacheTime๊ณผ StaleTime, ์–ธ์ œ ์กฐ์ •ํ•˜๋ฉด ์ข‹์„๊นŒ?

  • StaleTime์€ ๊ธฐ๋ณธ ๊ฐ’์ด 0์ด๋ฏ€๋กœ ์‘๋‹ต ์ฆ‰์‹œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋งŒ์•ฝ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์ž์ฃผ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๊ฒฝ์šฐ ๊ฐ’์„ ์กฐ์ •ํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ API ํ˜ธ์ถœ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ์œ ์ € ํ•œ ๋ช…์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค๋ฉด staleTime์„ infinity๋กœ ์„ค์ •ํ•ด์„œ ๋ถˆํ•„์š”ํ•œ ์š”์ฒญ์„ ๋ฐฉ์ง€ํ•˜๊ณ  POST, PUT, DELETE ๋“ฑ ๋ณ€์ด๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋งŒ ์ฟผ๋ฆฌ ๋ฌดํšจํ™”๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐฑ์‹ ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

 

 

 

5๏ธโƒฃ useMutation
  • POST, PUT, DELETE์™€ ๊ฐ™์€ ๋ณ€๊ฒฝ ๋ฐ ์ˆ˜์ •์ž‘์—…์„ ์„œ๋ฒ„์— ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ›…์ด๋‹ค.
  • mutate ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝœ๋ฐฑ์„ ํ†ตํ•œ ํŠธ๋ฆฌ๊ฑฐ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
  • const requestData = useMutation(API, mutationFn); ํ˜•์‹์œผ๋กœ ๊ตฌ์„ฑ.
  • quaryFn๊ณผ ๋‹ค๋ฅด๊ฒŒ ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ด ๋‘” mutationFn์ด ์žˆ๋‹ค๋ฉด ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.
  • useQuery์™€ ๋™์ผํ•˜๊ฒŒ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋Š” data, ์—๋Ÿฌ ์ •๋ณด๋Š” error ๊ฐ์ฒด๋กœ, ์ฟผ๋ฆฌ ์ƒํƒœ๋Š” status ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

function Example() {
  const mutation = useMutation(newTodo => {
    return axios.post('/todos', newTodo)
  })

  return (
    <div>
      {mutation.isLoading ? (
        'Adding todo...'
      ) : (
        <>
          {mutation.isError ? (
            <div>An error occurred: {mutation.error.message}</div>
          ) : null}

          {mutation.isSuccess ? <div>Todo added!</div> : null}

          <button
            onClick={() => {
              mutation.mutate({ id: new Date(), title: 'Do Laundry' })
            }}
          >
            Create Todo
          </button>
        </>
      )}
    </div>
  )
}
useMutation(exampleMutation, {
   onMutate: (variables) => {
     // mutate ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹คํ–‰ํ•  ๋‚ด์šฉ
     console.log(variables) // exampleMutation์— ๋“ค์–ด๊ฐ€๋Š” Arguments
   },
   onSuccess: (data, variables) => {
     // ์„ฑ๊ณต์‹œ ์‹คํ–‰ํ•  ๋‚ด์šฉ
   },
   onError: (error, variables) => {
     // ์—๋Ÿฌ์‹œ ์‹คํ–‰ํ•  ๋‚ด์šฉ
   },
   onSettled: (data, error, variables, context) => {
     // ์„ฑ๊ณต or ์—๋Ÿฌ ์ƒ๊ด€ ์—†์ด ์‹คํ–‰ํ•  ๋‚ด์šฉ
   },
 })

 

 

 

6๏ธโƒฃ devtools
  • devtools๋Š” TanStack Query๋ฅผ ์„ค์น˜ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์„ค์น˜๋˜๊ณ , ๋ณ„๋‹ค๋ฅธ ์„ค์ • ์—†์ด QueryClientProvider ๋ฒ”์œ„ ๋‚ด์— ReactQueryDevtools๋ฅผ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค.
  • ๊ฐ ์ฟผ๋ฆฌํ‚ค์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ์˜ ์ƒํƒœ๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • devtool์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๊ณต์‹๋ฌธ์„œ ์„ค๋ช…์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ !

 

import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* The rest of your application */}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  )
}

 

 

 

 

๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป ๊ฒฐ๋ก 
  • TanStack Query๋Š” ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋˜ ์ฟผ๋ฆฌ๋“ค ๋ง๊ณ ๋„ ๋‹ค์–‘ํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ํ›จ์”ฌ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.
  • ๋ฌด์—‡๋ณด๋‹ค ๋น„๋™๊ธฐ(API ํ˜ธ์ถœ ๋“ฑ) ์ž‘์—…์— ์ตœ์ ํ™”๋˜์–ด์žˆ๋Š” TanStack Query๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๋ฒ„์ „์— ์œ ์˜ํ•˜์—ฌ ์ฐธ๊ณ  ์ž๋ฃŒ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๊ณ  ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.
  • TanStack Query ์˜ ํ•ต์‹ฌ๊ธฐ๋Šฅ์œผ๋กœ๋Š” HTTP์˜ GET์š”์ฒญ๊ณผ ๊ฐ™์ด ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” useQuery ํ›…์ด ์žˆ๊ณ , POST, PUT, DELETE ์š”์ฒญ ๋“ฑ ๋ณ€์ด(์‚ฌ์ด๋“œ์ดํŽ™ํŠธ)๋ฅผ ์œ ๋ฐœํ•˜๋Š” useMutationํ›…์ด ์žˆ๋‹ค.

 

 

 

 

๋ฐ˜์‘ํ˜•