Tanstack Query with Next.js

์ด๋ฒˆ์— Next.js๊ฐ€ 15๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋˜๋ฉด์„œ fetch ์— ๋Œ€ํ•ด ์บ์‹ฑ ์—ฌ๋ถ€, stale time ์กฐ์ • ๋“ฑ์˜ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. ๋ฌธ๋“ ๋“  "๊ทธ๋™์•ˆ Tanstack Query ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋น„๋™๊ธฐ ์š”์ฒญ์— ๋Œ€ํ•ด ์บ์‹ฑ/stale ์กฐ์ •, ์„œ๋ฒ„ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์ง„ํ–‰ํ–ˆ๋Š”๋ฐ, ์ด์ œ ๊ตณ์ด ์‚ฌ์šฉ ์•ˆํ•ด๋„ ๋˜์ง€ ์•Š์„๊นŒ?" ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. ๊ฐ๊ฐ์˜ ๊ธฐ์ˆ ์„ ์ •๋ฆฌํ•˜๋ฉฐ ํŒ๋‹จํ•ด๋ณด์ž.

๊ณต์‹๋ฌธ์„œ์—์„œ Tanstack Query๋Š” it makes fetching, caching, synchronizing and updating server state in your web applications a breeze. ๋ผ๊ณ  ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๋ฒˆ์—ญํ•˜์ž๋ฉด ๋ฐ์ดํ„ฐ Fetching, ์บ์‹ฑ, ์„œ๋ฒ„ ๋ฐ์ดํ„ฐ์˜ ์—…๋ฐ์ดํŠธ์™€ ๋™๊ธฐํ™”๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ด์ค€๋‹ค ๋ผ๋Š” ๋ง์ด๋‹ค. Tanstack Query๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ช…ํ™•ํ•œ ์ด์œ ๊ฐ€ ๋“ค์–ด์žˆ๋Š” ํ•œ๋ฌธ์žฅ์ด๋‹ค.

๊ธฐ์กด ์„œ๋ฒ„์ƒํƒœ๊ด€๋ฆฌ์˜ ์œ ์˜์ ์€ ๋ฐ”๋กœ ์บ์‹ฑ, ๋™๊ธฐํ™”, ์—…๋ฐ์ดํŠธ๋‹ค.

์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์‹  ๋ฐ์ดํ„ฐ์™€ ๋™๊ธฐํ™”ํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์–ผ๋งˆ๋‚˜ ์บ์‹ฑํ•ด ์‚ฌ์šฉํ•  ๊ฒƒ์ธ์ง€, ์–ธ์ œ ๋‹ค์‹œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ์—…๋ฐ์ดํŠธํ• ๊ฒƒ์ธ์ง€๋ฅผ ๋‹ค๋ค„์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ธฐ์กด ํ”„๋ ˆ์ž„์›Œํฌ (eg. react)์—์„œ๋Š” ์ด๊ฒƒ์„ useState Hook์„ ์‚ฌ์šฉํ•ด ํ•ด๊ฒฐํ–ˆ๋‹ค. ๋ฌผ๋ก  ๊ตฌํ˜„๊ณผ ๋ณ„๊ฐœ๋กœ ์ฝ”๋“œ๊ฐ€ ๋งค์šฐ ๊ธธ์–ด์ง€๊ณ  ๊ฐ€๋…์„ฑ ๋˜ํ•œ ๋–จ์–ด์กŒ๋‹ค. ์ด๊ฒƒ์„ ๋ฉ”์„œ๋“œ ํ•˜๋‚˜๋กœ ์†์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•ด์ค€ ๊ฒƒ์ด ๋ฐ”๋กœ Tanstack Query๋‹ค.

function Example() {
  const { isPending, error, data } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      fetch('https://api.github.com/repos/TanStack/query').then((res) =>
        res.json(),
      ),
  })

  if (isPending) 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>
  )
}

์ด๋ฒˆ์—” ๋ฐ์ดํ„ฐ Fetching ๋ชจ๋ฒ” ์‚ฌ๋ก€์— ๋Œ€ํ•œ Next.js v15 ๊ณต์‹๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด์ž.

  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ฒ„ ์ธก์—์„œ Fetching

  • Suspense, Loading UI๋ฅผ ํ†ตํ•œ ์ ์ง„์  Rendering

์ •๋„๋กœ ์š”์•ฝํ•ด ๋ณผ์ˆ˜ ์žˆ๋‹ค.

async function getData() {
  const res = await fetch('https://api.example.com/...', { 
    next: { revalidate: 10 },
    cache: 'force-cache'
  );
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}
 
export default async function Page() {
  const data = await getData();
 
  return <main></main>;
}

๊ธฐ๋ณธ์ ์œผ๋กœ Next.js 15์˜ Fetch ๋Š” ์บ์‹ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด์— ๋”ฐ๋ผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜ต์…˜์„ ํ†ตํ•ด ์บ์‹ฑ ์˜ต์…˜์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, revalidate ๋˜ํ•œ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ฆ‰, ์ด์ „์— Tanstack Query๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์–ป๋Š” ์ด์ ์„ Next.js์˜ ๋นŒํŠธ์ธ ๋ฉ”์„œ๋“œ๋กœ๋„ ์–ป์„์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  Tanstack Query์—์„œ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ๊ธฐ๋Šฅ๋“ค์„ Next.js 15๋กœ ๋Œ€์ฒดํ• ์ˆ˜ ์žˆ๋Š”๊ฐ€? ๋ผ๋Š” ์งˆ๋ฌธ์—๋Š” ์•„๋‹ˆ์˜ค ๋ผ๊ณ  ํ• ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ˆœ ๋ฐ์ดํ„ฐ Fetching ๋กœ์ง๋“ค์€ Next.js 15์˜ Fetch๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ๊ฐ„ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋ฐ˜์˜ ๋“ฑ ๋ณต์žกํ•œ ์ƒํƒœ๊ด€๋ฆฌ๋‚˜, ๋ฐ์ดํ„ฐ ์˜์กด์„ฑ ๊ด€๋ฆฌ์— ์žˆ์–ด์„œ Tanstack Query๋Š” ์—ฌ์ „ํžˆ ๋งค๋ ฅ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

๋‹ค๋งŒ, ์ด๋ฒˆ 15๋ฒ„์ „ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ๋นŒํŠธ์ธ ๊ธฐ๋Šฅ๋งŒ์œผ๋กœ ์ถ”๊ฐ€์ ์ธ ์˜์กด์„ฑ ์—†์ด ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”ํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๋ฐœ์ „๋œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ๊ธฐ๋Œ€ํ•ด ๋ณผ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

Last updated