Front-End/Library

Library] SWR

์™•๊ฐ€๐Ÿ‘ 2023. 7. 3. 10:46
728x90
๋ฐ˜์‘ํ˜•

SWR(Stale-While-Revalidate)

swr์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ React hook ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„์— GET์š”์ฒญ์„ ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์™€ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ˆœํžˆ axios๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํšจ์œจ์ด ์ข‹๋‹ค๊ณ  ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๋Œ€ํ‘œ์ ์ธ ํŠน์ง•์œผ๋กœ

  • ๋น ๋ฅด๊ณ , ๊ฐ€๋ณ๊ณ , ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
  • ๋‚ด์žฅ๋œ ์บ์‹œ ๋ฐ ์š”์ฒญ ์ค‘๋ณต์„ ์ œ๊ฑฐ
  • ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋™์ž‘

3๊ฐ€์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์„ ๋“ฏํ•ฉ๋‹ˆ๋‹ค.

(์ €๋Š” ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ค‘๋ณต์œผ๋กœ ์š”์ฒญ์„ ์•ˆ ํ•œ๋‹ค๋Š” ๊ฒŒ ํฐ ์žฅ์ ์œผ๋กœ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.)

 

๊ณต์‹ ํ™ˆํŽ˜์ด์ง€๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

https://swr.vercel.app/ko

 

 


 

 

์„ค์น˜

npm i swr
yarn add swr

 

 


 

 

๊ธฐ๋ณธ ๊ตฌ์„ฑ

const { data, error, isLoading, isValidating, mutate } = useSWR(key, fetcher, options)

 

parameter

  • key : ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์ž์—ด๋กœ ๋ณดํ†ต URL.
  • fetcher : ํ•จ์ˆ˜์— key๊ฐ’์„ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ.
    promise๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ, fetch๋‚˜ axios ๋“ฑ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋ฐ˜ํ™˜๊ฐ’์ด data์— ํ•ด๋‹น
  • options : ๋‹ค์–‘ํ•œ ์˜ต์…˜์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ ์‚ญ์ œ ํ•  ์ˆ˜ ์žˆ์Œ. ์•„๋ž˜ ๋งํฌ์— ์ž์„ธํžˆ ๊ธฐ์žฌ
https://swr.vercel.app/ko/docs/api

 

 


 

 

return

  • data : fetcher์—์„œ ์„ฑ๊ณต์ ์œผ๋กœ ํ†ต์‹ ์„ ํ–ˆ์„ ๋•Œ ๋ฆฌํ„ด๋˜๋Š” ๊ฐ’
  • error : fetcher์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋ฆฌํ„ด๋˜๋Š” ๊ฐ’.
  • isLoading : ํ†ต์‹  ์ค‘์ธ์ง€ ํ™•์ธ.
  • isValidating : ์š”์ฒญ์ด๋‚˜ ๊ฐฑ์‹  ์—ฌ๋ถ€.
  • mutate : useSWR๋กœ ์„ ์–ธํ•œ key์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์‹ ํ™”ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์—ญํ• 

 

 


 

 

error

์•ž์—์„œ ๋งํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ fetcher์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด, error๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

const fetcher = async url => {
  const res = await axios.get(url)
 
  if (!res.ok) {
    const error = new Error('An error occurred while fetching the data.')

    error.info = await res.json()
    error.status = res.status
    throw error
  }
 
  return res.json()
}

 

axios.get์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ–ˆ๊ณ ,

ok๋กœ ๋–จ์–ด์ง€์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ new Error๋กœ ์—๋Ÿฌ ์ƒ์„ฑ ํ›„, status๋‚˜ info๋ฅผ ํŒŒ์‹ฑ ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

res.ok๋ฅผ ์•ˆ๋ณด๊ณ , try catch ๋ฌธ์œผ๋กœ ์—๋Ÿฌ ์žก์•„๋„ ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.

 

useSWR('/api/user', fetcher, {
  onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
    // 404์—์„œ ์žฌ์‹œ๋„ ์•ˆํ•จ
    if (error.status === 404) return
 
    // ํŠน์ • ํ‚ค์— ๋Œ€ํ•ด ์žฌ์‹œ๋„ ์•ˆํ•จ
    if (key === '/api/user') return
 
    // 10๋ฒˆ๊นŒ์ง€๋งŒ ์žฌ์‹œ๋„ํ•จ
    if (retryCount >= 10) return
 
    // 5์ดˆ ํ›„์— ์žฌ์‹œ๋„
    setTimeout(() => revalidate({ retryCount }), 5000)
  }
})

 

์—๋Ÿฌ ๋‚ฌ์„ ๋•Œ onErrorRetry ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜ต์…˜์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

isLoading & isValidating

isLoading๊ณผ isValidating์€ ์„œ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

  • isLoading์€ ์ง„ํ–‰ ์ค‘์ธ ์š”์ฒญ์ด ์žˆ๊ณ , ์•„์ง ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ true
  • isValidating์€ ๋ฐ์ดํ„ฐ ๋กœ๋“œ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ์ง„ํ–‰ ์ค‘์ธ ์š”์ฒญ์ด ์žˆ์„ ๋•Œ true

์ด๋ ‡๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ,

๊ฐ„๋‹จํžˆ ์ฒ˜์Œ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ๋Š” ๋‘˜ ๋‹ค true์ธ ์ƒํƒœ์ด๊ณ , ๋ฐ์ดํ„ฐ ๊ฐฑ์‹ ๋  ๋•Œ๋Š” isValidating๋งŒ true๋ผ๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ณตํ™ˆ์— ์žˆ๋Š” ๋™์ž‘

 


 

 

์‚ฌ์šฉ๋ฒ•

import useSWR from "swr";

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

  if (error) return <div>failed</div>;
  if (isLoading) return <div>loading</div>;
  return <div>{data.name}</div>;
}
// fetcher.js

import axios from 'axios';

const fetcher = (url: string) => {
  return axios.get(url, { withCredentials: true, })
      .then((res) =>  res.data);
};

export default fetcher;

 

๊ฐ„๋‹จํ•˜๊ฒŒ user์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ด…์‹œ๋‹ค.

key๊ฐ’์œผ๋กœ ๋“ค์–ด๊ฐ„ url์€ '/api/user'๊ฐ€ ๋˜๊ณ ,

fetcher๋Š” ๋”ฐ๋กœ ์ •์˜ํ•ด ๋‘์—ˆ๊ณ  key๊ฐ’์ด fetcher์˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ ํ›„ axios.get์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

ํ†ต์‹ ์ด ๋๋‚˜๊ฒŒ  ๋˜๋ฉด, ๋ฆฌํ„ด๋œ data๋Š” ๋กœ์ปฌ์— ์ €์žฅ๋˜๊ฒŒ ๋˜๊ณ , ์ด data๋Š” ๋ณ„๋„๋กœ ์š”์ฒญ์ด ์—†๋Š” ํ•œ ์บ์‹ฑ๋˜์–ด ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ง€๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹นํ•˜๋Š” data๋ฅผ ๋‹ค์‹œ ๋ถ€๋ฅด๊ฒŒ ๋˜๋ฉด ์บ์‹ฑ๋œ data๊ฐ€ ์žฌ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

 


 

 

 

๋‹ค์Œ ๊ฒŒ์‹œ๊ธ€์—์„œ mutate๋ฅผ ํฌํ•จํ•ด ์ข€ ๋” ๋‹ค์–‘ํ•œ ๋ถ€๋ถ„์„ ์ž‘์„ฑํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
728x90

'Front-End > Library' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Library] SWR : ์‘์šฉ_Mutate & Revalidation  (0) 2023.07.03
Library] SWR : ์‘์šฉ  (0) 2023.07.03
Library] Swiper  (0) 2023.06.29
Library] Axios : ์‘์šฉ  (0) 2023.06.28
Library] Axios  (0) 2023.06.27