5.usehooks-ts

  • A simple abstraction to play with a boolean, don't repeat yourself. (๋ถ€์šธ์„ ๊ฐ€์ง€๊ณ  ๋†€๊ธฐ ์œ„ํ•œ ๊ฐ„๋‹จํ•œ ์ถ”์ƒํ™”, ๋ฐ˜๋ณตํ•˜์ง€ ๋งˆ์„ธ์š”.)

  • Just modified version of useEffect that's executed only one time, at the mounting time. (๋งˆ์šดํŒ… ์‹œ์ ์— ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” ์‚ฌ์šฉ ํšจ๊ณผ์˜ ์ˆ˜์ •๋œ ๋ฒ„์ „์ด๋‹ค.)

  • Here is a React Hook which aims to retrieve data on an API using the native Fetch API. (๋‹ค์Œ์€ ๋„ค์ดํ‹ฐ๋ธŒ Fetch API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” React Hook์ด๋‹ค.)

  • I used a reducer to separate state logic and simplify testing via functional style. (์ƒํƒœ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ณ  ํ•จ์ˆ˜ํ˜• ์Šคํƒ€์ผ์„ ํ†ตํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ๋“€์„œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.)

  • The received data is saved (cached) in the application via useRef, but you can use LocalStorage (see useLocalStorage()) or a caching solution to persist the data. (์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ๋Š” useRef๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ €์žฅ(์บ์‹œ)๋˜์ง€๋งŒ, ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์†์‹œํ‚ค๊ธฐ ์œ„ํ•ด LocalStorage(useLocalStorage() ์ฐธ์กฐ) ๋˜๋Š” ์บ์‹ฑ ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.)

  • The fetch is executed when the component is mounted and if the url changes. If ever the url is undefined, or if the component is unmounted before the data is recovered, the fetch will not be called. (์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋˜๊ณ  URL์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์‹คํ–‰๋œ๋‹ค. URL์ด ์ •์˜๋˜์ง€ ์•Š์•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณต๊ตฌ๋˜๊ธฐ ์ „์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ํ•ด์ œ๋˜๋ฉด ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋‹ค.)

  • This hook also takes the request config as a second parameter in order to be able to pass the authorization token in the header of the request, for example. Be careful though, the latter does not trigger a re-rendering in case of modification, go through the url params to dynamically change the request. (์ด ํ›…์€ ๋˜ํ•œ ์š”์ฒญ์˜ ํ—ค๋”์— ์ธ์ฆ ํ† ํฐ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์š”์ฒญ ๊ตฌ์„ฑ์„ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•œ๋‹ค(์˜ˆ: ์š”์ฒญ ํ—ค๋”์— ์ธ์ฆ ํ† ํฐ ์ „๋‹ฌ). ํ•˜์ง€๋งŒ ํ›„์ž๋Š” ์š”์ฒญ์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด URL ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์š”์ฒญ์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ ์žฌ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•˜์„ธ์š”.)

  • Use setInterval in functional React component with the same API. (๋™์ผํ•œ API๋ฅผ ๊ฐ€์ง„ ํ•จ์ˆ˜ํ˜• React ์ปดํฌ๋„ŒํŠธ์—์„œ setInterval ์‚ฌ์šฉ.)

  • Set your callback function as a first parameter and a delay (in milliseconds) for the second argument. (์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜์˜ ์ง€์—ฐ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)์„ ์„ค์ •ํ•œ๋‹ค.)

  • You can also stop the timer passing null instead the delay or even, execute it right away passing 0. (์ง€์—ฐ ๋Œ€์‹  0์„ ์ „๋‹ฌํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์ค‘์ง€ํ•˜๊ฑฐ๋‚˜ 0์„ ์ „๋‹ฌํ•˜๋Š” ํƒ€์ด๋จธ๋ฅผ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.)

  • The main difference between the setInterval you know and this useInterval hook is that its arguments are "dynamic". (์—ฌ๋Ÿฌ๋ถ„์ด ์•Œ๊ณ  ์žˆ๋Š” setInterval๊ณผ ์ด useInterval ํ›…์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ ๊ทธ ์ธ์ˆ˜๊ฐ€ "๋™์ "์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค.)

  • You can get more information in the Dan Abramov's blog post. (๋Œ„ ์•„๋ธŒ๋ผ๋ชจํ”„์˜ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.)

  • Use EventListener with simplicity by React Hook. (์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ React Hook์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์„ธ์š”.)

  • Supports Window, Element and Document and custom events with almost the same parameters as the native addEventListener options. (๊ธฐ๋ณธ ์ถ”๊ฐ€ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์˜ต์…˜๊ณผ ๊ฑฐ์˜ ๋™์ผํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฐฝ, ์š”์†Œ, ๋ฌธ์„œ ๋ฐ ์‚ฌ์šฉ์ž ์ง€์ • ์ด๋ฒคํŠธ๋ฅผ ์ง€์›ํ•œ๋‹ค.)

  • Persist the state with local storage so that it remains after a page refresh. (ํŽ˜์ด์ง€ ์ƒˆ๋กœ ๊ณ ์นจ ํ›„์—๋„ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜๋„๋ก ๋กœ์ปฌ ์ €์žฅ์†Œ๋กœ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.)

  • This can be useful for a dark theme. This hook is used in the same way as useState except that you must pass the storage key in the 1st parameter. (์–ด๋‘์šด ํ…Œ๋งˆ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ํ›…์€ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ €์žฅ์†Œ ํ‚ค๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๋ฉด useState์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.)

  • If the window object is not present (as in SSR), useLocalStorage() will return the default value. (window ๊ฐ์ฒด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ(SSR์—์„œ์™€ ๊ฐ™์ด) useLocalStorage()๋Š” ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.)

  • This React Hook offers you an interface to enable, disable, toggle and read the dark theme mode. (์ด React Hook์€ ์–ด๋‘์šด ํ…Œ๋งˆ ๋ชจ๋“œ๋ฅผ ํ™œ์„ฑํ™”, ๋น„ํ™œ์„ฑํ™”, ํ† ๊ธ€ ๋ฐ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.)

  • The returned value (isDarkMode) is a boolean to let you be able to use with your logic. (๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’(isDarkMode)์€ ๋กœ์ง์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ถ€์šธ์ด๋‹ค.)

  • It uses internally useLocalStorage() to persist the value and listens the OS color scheme preferences. (๋‚ด๋ถ€์ ์œผ๋กœ useLocalStorage()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ์œ ์ง€ํ•˜๊ณ  OS ์ƒ‰ ๊ตฌ์„ฑํ‘œ ๊ธฐ๋ณธ ์„ค์ •์„ ์ˆ˜์‹ ํ•œ๋‹ค.)

SWR์€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ์บ์‹ฑ ๋ฐ ์žฌ๊ฒ€์ฆ์„ ์œ„ํ•œ React hook ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. ์ด๋ฆ„์€ HTTP RFC 5861์— ์˜ํ•ด ์•Œ๋ ค์ง„ HTTP ์บ์‹œ ๋ฌดํšจ ์ „๋žต์ธ "stale-while-revalidate"์—์„œ ์œ ๋ž˜๋˜์—ˆ๋‹ค. SWR์„ ์‚ฌ์šฉํ•˜๋ฉด API, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋˜๋Š” ๊ธฐํƒ€ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ๋‹ค์Œ React ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ž๋™ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

SWR์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•  ๋•Œ ๊ตฌ์„ฑ ์š”์†Œ์— ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•˜๋Š” ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ตฌํ˜„ํ•˜์—ฌ ์ด๋ฅผ ๋‹ฌ์„ฑํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๋ž˜๋œ ๊ฒฝ์šฐ(์ฆ‰, ์˜ค๋ž˜๋œ ๊ฒฝ์šฐ) SWR์€ ์„œ๋ฒ„์—์„œ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ๋‹ค์Œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด UI๊ฐ€ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋กœ ๋ฐ˜์‘ํ•˜๊ณ  ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

SWR์€ REST API, GraphQL ์—”๋“œํฌ์ธํŠธ, ์‹ฌ์ง€์–ด ์›น ์†Œ์ผ“์„ ํฌํ•จํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ง€์›ํ•œ๋‹ค. ๋˜ํ•œ ์ž๋™ ์œ ํšจ์„ฑ ์žฌ๊ฒ€์‚ฌ, ํด๋ง ๋ฐ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. SWR์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์ž๋™ ์บ์‹ฑ: SWR์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ž๋™์œผ๋กœ ์บ์‹ฑํ•˜๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด API ํ˜ธ์ถœ ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋œ๋‹ค.

  2. Stale-while-revalidate: ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๋ž˜๋˜๋ฉด SWR์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์„œ๋ฒ„์—์„œ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด UI๊ฐ€ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋กœ ์‘๋‹ตํ•˜๊ณ  ์ตœ์‹  ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

  3. ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ: SWR์€ ์›น ์†Œ์ผ“๊ณผ ๊ฐ™์ด ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ๋Œ€ํ•œ ์‹ค์‹œ๊ฐ„ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์›ํ•œ๋‹ค.

  4. ์œ ์—ฐํ•œ ๊ตฌ์„ฑ: SWR์€ ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋งž๊ฒŒ ์บ์‹ฑ ๋ฐ ์žฌ๊ฒ€์ฆ ๋™์ž‘์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐํ•œ ๊ตฌ์„ฑ API๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

import useSWR from 'swr'

function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)

  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

React Query๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌ, ์บ์‹ฑ ๋ฐ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•œ React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. API ๋ฐ ๊ธฐํƒ€ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ์บ์‹ฑํ•˜๊ณ , ์—…๋ฐ์ดํŠธํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ฐ„์†Œํ™”ํ•œ๋‹ค. React Query๋Š” ์„ ์–ธ์ ์ด๊ณ  ํšจ์œจ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋ จ์˜ hook์„ ์ œ๊ณตํ•œ๋‹ค.

React Query๋Š” ์ž๋™ ์บ์‹ฑ, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ, ์Šค๋งˆํŠธ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค. ๋˜ํ•œ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ํ•ญ์ƒ ์„ฑ๊ณตํ•˜๋„๋ก ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์žฌ์‹œ๋„ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค.

React Query์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์บ์‹ฑ: React Query๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์ˆ˜๋ฅผ ์ค„์ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค.

  2. ์ž๋™ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ: React Query๋Š” UI๊ฐ€ ํ•ญ์ƒ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜์˜ํ•˜๋„๋ก ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๊ฐ€์ ธ์˜จ๋‹ค.

  3. ์Šค๋งˆํŠธ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”: React Query๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋™๊ธฐํ™”๋˜๋„๋ก ํ•˜๋ฏ€๋กœ ์ˆ˜๋™ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.

  4. ๋กœ๋”ฉ ๋ฐ ์˜ค๋ฅ˜ ์ƒํƒœ: React Query๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด์žฅ ๋กœ๋”ฉ ๋ฐ ์˜ค๋ฅ˜ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

  5. ๋ณ‘๋ ฌ ์ฟผ๋ฆฌ: React Query๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ‘๋ ฌ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ์ค„์–ด๋“ค์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋œ๋‹ค.

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

const queryClient = new QueryClient()

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

function Example() {
  const { isLoading, error, data } = useQuery({
    queryKey: ['repoData'],
    queryFn: () =>
      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>
  )
}

Last updated