API

๋ฐ˜๋ณต๋˜๋Š” API Call

  • ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” API๋Š” ์บ์‹ฑํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด API ํ˜ธ์ถœ ๋น„์šฉ๊ณผ ์‘๋‹ต์‹œ๊ฐ„์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” API๋„ ์บ์‹ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ˜ธ์ถœ ๋น„์šฉ์€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ๋ณด์—ฌ์ฃผ๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ API๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐฑ์‹ ํ•ด์ค€๋‹ค๋ฉด ์‘๋‹ต์‹œ๊ฐ„ ์ธก๋ฉด์˜ ์ด๋“์œผ๋กœ ์ธํ•ด ์œ ๋ คํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Prefetching

pre-fetch, ๋ Œ๋”๋ง ์ด์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐ›์•„๋†“๊ธฐ

Client Side Prefetching

  • router-prefetch โ†’ ์ด๋™ํ•  ๋ผ์šฐํ„ฐ์˜ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ fetching

  • client side์˜ transition์„ ๋น ๋ฅด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ

  • next/link ๋Š” ์ž๋™์œผ๋กœ prefetching

  • next/link ์˜ <Link/> ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ์œ ์˜๋ฏธํ•˜๋‹ค.

const router = useRouter(); 

useEffect(() => {
  router.prefetch('/dashboard')
}, [router])

Server Side Prefetching

  • ๋ Œ๋”๋ง์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์„œ๋ฒ„์—์„œ fetch ํ•˜์—ฌ ๋ Œ๋”๋ง ์‹œ ๋ฐ”๋กœ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต

  • initialData prop โ†’ getServerSideProps, getStaticProps ๋“ฑ์„ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„ data๋ฅผ ๋ฏธ๋ฆฌ fetchingํ•˜๊ณ  props๋กœ ๋„˜๊ฒจ useQuery์˜ initialData๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹

    • ๋‹จ์  โ†’ useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ props๋กœ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•˜๋ฏ€๋กœ props driling์ด ์‹ฌํ•ด์ง€๊ณ  refetching ์‹œ์ ์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

export const getStaticProps = async() => {
  const posts = await getPosts();
  return {props: { posts }}
}

const Posts = ({ posts  }) => {
  const { data } = useQuery({
    queryKey: ['posts'],
    queryFn: getPosts,
    initialData: posts
   })
}
  • hydration prefetching โ†’ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ getServerSideProps, getStaticProps ์„ ์ด์šฉํ•˜์—ฌ ์„œ๋ฒ„์—์„œ fetchingํ•œ ๋ฐ์ดํ„ฐ๋ฅผ queryClient์— ๋‹ด์•„ dehydrateState๋กœ ๋„˜๊ฒจ์ฃผ๊ณ  <Hydrate /> HOC๋กœ ์ „๋‹ฌํ•œ๋‹ค.

    • Hydrate HOC๋Š” ๋ฐ›์€ state๋ฅผ client์˜ queryClient๋กœ ์…‹์—…์„ ์ง„ํ–‰ํ•œ๋‹ค.

    • ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋Š” useQuery์—์„œ stale data๋กœ ์ทจ๊ธ‰๋˜์–ด ๋ Œ๋”๋ง์ด ์šฐ์„  ์ง„ํ–‰๋˜๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ตœ์‹ ๋ฐ์ดํ„ฐ๋ฅผ refetch ๋ฐ›์•„ ๊ต์ฒดํ•ด์ค€๋‹ค.

Caching

  • Stale โ†’ ์ด์ „์— fetch๋œ ์‹ ์„ ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ

    • ์‹ ์„ ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„  ๋ณด์—ฌ์ฃผ๊ณ  ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌํŒจ์นญํ•˜๋Š” ๊ณผ์ •์ด ์ง„ํ–‰๋œ๋‹ค.

    • stale time(default 0s) ๋งŒํผ fresh ์ƒํƒœ๋กœ ์กด์žฌํ•˜๋‹ค๊ฐ€ stale ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ๋จ

    • stale ์ƒํƒœ์—์„  ํŠน์ • Refetching ์กฐ๊ฑด ์ถฉ์กฑ์‹œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ refetching ๊ณผ์ •์ด ์ผ์–ด๋‚จ

      • ์ƒˆ QueryInstance๊ฐ€ ๋งˆ์šดํŠธ ๋  ๋•Œ (ํŽ˜์ด์ง€ ์ด๋™)

      • ๋ธŒ๋ผ์šฐ์ € ํƒญ focus out/in ์ „ํ™˜ ์‹œ

      • ๋„คํŠธ์›Œํฌ๊ฐ€ ์žฌ์—ฐ๊ฒฐ ๋  ๋•Œ

      • refetchInterval ์„ค์ • ์‹œ

  • Cache โ†’ fetch ๋˜์–ด ์žฌ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ

    • cache time(default 5m)๋™์•ˆ ์ €์žฅ๋œ๋‹ค.

    • QueryCache ๋‚ด๋ถ€ queries์— ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜๋Š” ์ƒํƒœ

Persist Caching

  • ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๊ฐ€ ์•„๋‹Œ ๋ธŒ๋ผ์šฐ์ € ๋‚ด ์Šคํ† ๋ฆฌ์ง€์— ์บ์‹ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์—ฌ ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•ด๋„ refetching ํ•˜์ง€ ์•Š๊ณ  ์ด์ „์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

if (typeof window === 'undefined') {
  return (
    <QueryClientProvider client={queryClient}>
      <Component {...pageProps} />
    </QueryClientProvider>
  )
}

return (
  <PersistQueryClientProvider 
    client={queryClient}
    persistOptions={{
      persister: createSyncStoragePersister({
        storage: window.localStorage // or window.sessionStorage
      })
    }}
  >
    <Hydrate state={state}>
      <Component {...pageProps} />
    </Hydrate>
  </QueryClientProvider>
)

Last updated