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๋ฅผ ํฌํจํด ์ข ๋ ๋ค์ํ ๋ถ๋ถ์ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
'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 |