swr์ ์์ธํ ์ค๋ช ์ ๊ณต์๋ฌธ์๋ฅผ ์ฝ๋ ๊ฒ์ด ๋ ์ข๋ค๊ณ ์๊ฐํด์ ์ ์ฒด์ ์ผ๋ก ์ ๋ฆฌํจ๊ณผ ๋์์ ์ดํดํ ๋ถ๋ถ์ ๋ํ ๋ณต์ต์ฐจ์์์ ์์ฑํ๊ฒ ์ต๋๋ค.
SWR
์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํจ์นํ๋๋ฐ ์ฌ์ฉํฉ๋๋ค.
ํ์ง๋ง ๋ฐ์ดํฐ ํจ์น๋ fetch
๋ axios
๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก๋ ์ถฉ๋ถํ ๊ฐ๋ฅํ๋ฐ ๊ตณ์ด ์ถ๊ฐ๋ก ๊ณต๋ถ๊ฐ ํ์ํ SWR
์ ์ฌ์ฉํ๋ ์ด์ ๊ฐ ๋ฌด์์ธ์ง์ ๋ํด์ ์ ๊ฐ ๋๋๋๋ก ์ ์ด๋ณด๋ ค๊ณ ํฉ๋๋ค.
์ผ๋จ ๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด fetch
๋ axios
๋ ๋ฐ์ดํฐ ํจ์นญ์ ๊ธฐ๋ฅ ์ด์ธ์๋ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ ํ ์๋ ๊ฑธ๋ก ์๊ณ ์์ต๋๋ค.
๋ฌผ๋ก API
๋ฅผ ํธ์ถํ๊ธฐ ์ง์ ๊ณผ ์งํ์ ์ธํฐ์
ํฐ๋ก ๋ค๋ฅธ ๊ธฐ๋ฅ์ ์ํํ๋๋ก ํ ์๋ ์์ง๋ง ๊ทผ๋ณธ์ ์ผ๋ก API
๋ฅผ ์์ฒญํ๋ ์ญํ ๋ง ํฉ๋๋ค.
ํ์ง๋ง SWR
์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋ ์ดํ์ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋๋ฐ ์์ฒญ๋ ์ด์ ์ด ์์ต๋๋ค.
ํค์๋๋ก๋ง ์๋ฅผ ๋ค๋ฉด ๋ฐ์ดํฐ ์บ์ฑ, ์๋ ๊ฐฑ์ , ์๋ฌ ์ฒ๋ฆฌ ๋ฑ ์ง์ ๊ตฌํํ๊ธฐ ํ๋ ๋ง์ ๊ธฐ๋ฅ๋ค์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธ์ SWR
์ ์ฌ์ฉํ๋ ๊ฒ์ด ์๋๊ฐ ์๊ฐํฉ๋๋ค.
์ดํ ๋ด์ฉ๋ค์ ์ด๋ฐ ์ด์ ๋ค๊ณผ ์ฌ์ฉ๋ฒ์ ๋ํด์ ์ง์ ๊ฒฝํํด ๋ณธ ๋๋ก ์ ๋ฆฌํด ๋ณด๊ฒ ์ต๋๋ค.
( ์ถ๊ฐ๋ก typescript
๊ธฐ์ค์ผ๋ก ์ ๋ฆฌํ๊ฒ ์ต๋๋ค. )
npm i swr
import useSWR from "swr";
type UserResponse = {
id: number;
name: string;
email: string;
// ํ์
์ด ๋ง์์ ์ผ๋ถ๋ถ๋ง ์์ฑํ๊ฒ ์ต๋๋ค.
}
const fetcher = (url: string) => fetch(url).then(res => res.json());
const Component = () => {
const { data, error } = useSWR<UserResponse>("https://jsonplaceholder.typicode.com/users/1", fetcher)
if(error) return <h3>Failed to load<h3>;
if(!data && !error) return <h3>Loading<h3>;
return (
<section>
<div>{data.name}</div>
<div>{data.email}</div>
</section>
)
}
์ผ๋ฐ์ ์ผ๋ก useSWR<๋ฐํํ ๋ฐ์ดํฐ ํ์
>("์์ฒญ url", fetcher)
ํ์์ผ๋ก ์์ฑํฉ๋๋ค.
useSWR()
์ ์ฒซ ๋ฒ์งธ ์ธ์์ธurl
์ ์บ์ํ๊ธฐ์ํ ์ ์ผํ key๊ฐ ๋จ๊ณผ ๋์์fetcher()
์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
์ฌ๊ธฐ์ ์บ์ ํ๊ธฐ ์ํ ์ ์ผํ key๊ฐ ๋๋ค๋ ๋ง์ ์ค๋ช
ํ๊ธฐ์ ์์ SWR
์ ๋ํด ์์ ์ค๋ช
์ ํ๊ฒ ์ต๋๋ค.
SWR
์ ๊ธฐ๋ณธ์ ์ผ๋ก useSWR()
์ ํธ์ถํ ๋๋ง๋ค API
๋ฅผ ์์ฒญํ๋ ๊ฒ์ด ์๋๊ณ ๋ธ๋ผ์ฐ์ ํ๋ฉด ๋ฐ์ ๋๊ฐ๋ค๊ฐ ํฌ์ปค์ค ๋์ ๊ฒฝ์ฐ๋ ์ง์ ๋ ์๊ฐ ๋ฑ ์ฌ๋ฌ ๊ฐ์ง ์ํฉ์ ๋ง๊ฒ ์๋์ ์ผ๋ก API
๋ฅผ ์์ฒญํฉ๋๋ค.
API
์์ฒญ์ ์คํํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.๋ง์ฝ ๋ชจ๋ ํ์ด์ง๋ง๋ค useSWR()
์ ์ด์ฉํด์ ๊ฐ์ url
์ ์์ฒญ์ ๋ณด๋ธ๋ค๊ณ ํ๋๋ผ๊ณ SWR
์์ url
์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํด๋๊ธฐ ๋๋ฌธ์ ํ์ด์ง์ ์
์ฅํ ๋๋ง๋ค ํญ์ ์์ฒญ์ ๋ณด๋ด์ง ์๊ณ ๊ธฐ์กด์ ์์ฒญํ๋ key์ธ์ง ํ์ธํ๊ณ ๊ธฐ์กด์ ์์ฒญํ๋ค๋ฉด ์๋ ์บ์ฑํ๋ ๊ฐ์ ๋ฐํํด์ฃผ๊ณ , ์๋๋ผ๋ฉด ์๋ก์ด key๋ก url
์ ๋ฑ๋กํ๊ณ ์บ์ฑํ๊ฒ ๋ฉ๋๋ค.
์ ์ค๋ช
์ด url
์ด ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๊ธฐ ์ํ ์ ์ผํ key๊ฐ ๋๋ค๊ณ ํ๋ ๋ง์ ์๋ฏธ์
๋๋ค.
fetcher
๋ option
๋ค์ ์ ์ญ์ ์ผ๋ก ์ค์ ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
์ฌ์ฉํ ๋๋ ์ค๋ฒ๋ผ์ด๋ฉํด์ ๋
๋ฆฝ์ ์ผ๋ก ๋ค๋ฅธ fetcher
๋ option
์ ๋ถ์ฌํ ์ ์์ต๋๋ค.
import { SWRConfig } from "swr";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
const App = () => {
return (
<SWRConfig
value={{
fetcher,
}}
>
// ์ดํ ํ์ ์ปดํฌ๋ํธ๋ค์์ SWR์ ์ฌ์ฉํ๋ฉด ์ ์ญ์ ์ผ๋ก ์ง์ ํ ์ธํ
๊ฐ์ด ๋ค์ด๊ฐ๋๋ค.
<Component />
</SWRConfig>
)
}
const Component = () => {
// ์ ์ญ์ ์ผ๋ก fetcher๋ฅผ ์ง์ ํ์ผ๋ฏ๋ก ์๋ต์ด ๊ฐ๋ฅํ๊ณ , ํ์์ ์ํด์ ๋ค๋ฅธ fetcher๋ฅผ ์ ์ฉํ ์ ์์ต๋๋ค.
const { data, error } = useSWR<UserResponse>("https://jsonplaceholder.typicode.com/users/1");
if(error) return <h3>Failed to load<h3>;
if(!data && !error) return <h3>Loading<h3>;
return (
<section>
<div>{data.name}</div>
<div>{data.email}</div>
</section>
)
}
useSWR()
์ฌ์ฉ๋ฒconst { data, error, isValidating, mutate } = useSWR(key, fetcher, options)
/**
* data: fetcher๋ฅผ ์คํํ ์ฑ๊ณต์ ์ธ ๊ฒฐ๊ณผ
* error: fetcher์์ ๋ฐ์ํ ์ค๋ฅ
* isValidating: ์์ฒญ์ด๋ ๊ฐฑ์ ๋ก๋ฉ์ ์ฌ๋ถ
* mutate: ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฎคํ
์ดํธํ๊ธฐ ์ํ ํจ์ ( ๋ฎคํ
์ดํธ์ ๋ํด์๋ ๋ค์์ ์ค๋ช
)
* key: url์ด์ ์บ์ฑ์ ๊ตฌ๋ณํ๊ธฐ ์ํ ์ ์ผํ key
* fetcher: ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ Promiseํจ์๋ฅผ ๋ฐํํ๋ ํจ์ ( fetch, axios )
* options: ๋๋ฌด ๋ง๊ณ ํ์๋ ์ฌ์ฉ๊ฒฝํ์ด ๋ง์ง ์์ผ๋ฏ๋ก ๊ณต์๋ฌธ์ ์ฐธ๊ณ ๋ฐ๋
*/
import useSWR from "swr";
import useSWRImmutable from 'swr/immutable'
// ์๋ ๋๊ฐ๋ ์๋ฒฝํ๊ฒ ๊ฐ๊ฒ ๋์ํจ
useSWR(key, fetcher, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false
});
useSWRImmutable(key, fetcher)
import useSWR from "swr";
useSWR(router.query.id ? `/api/users/${router.query.id}` : null, fetcher);
useSWR(() => router.query.id ? `/api/users/${router.query.id}` : null, fetcher);
// ์ ๋๊ฐ์ง ๋ฐฉ๋ฒ ๋ชจ๋ ๊ฐ๋ฅ
/*
* key๋ก ๋ฌธ์์ด์ ๋๊ธธ๊ฒฝ์ฐ ๋ฐ๋ก key๋ก ์ฌ์ฉํ๊ณ , null์ ๋๊ธฐ๋ฉด ์์ฒญ์ ํ์ง ์์
* key๋ก ํจ์๋ฅผ ๋๊ธธ๊ฒฝ์ฐ ๋ฐํ๊ฐ์ key๋ก ์ฌ์ฉํ๋ฉฐ, falsy์ธ ๊ฐ์ ๋ฐํํ๋ฉด ์์ฒญํ์ง ์์
* ๋จ, ๋ฌธ์์ด์ ๋๊ธธ ๋ ์ ์๋์ง ์์ ๊ฐ์ ๋๊ธฐ๋ฉด ์ค๋ฅ ๋ฐ์
* ์๋ฅผ ๋ค๋ฉด router.query.id ๊ฐ์ ์ฆ์ ๊ฐ์ ธ์์ง์ง ์์ผ๋ฏ๋ก undefined์ธ ๊ฐ์ด ๋ค์ด๊ฐ ์ ์์
* undefined๋ฅผ ๋ฐ๋ก ์ฌ์ฉํด์ ์์ฒญํ๋ฉด ์๋ฌ ๋ฐ์
*/