-
Notifications
You must be signed in to change notification settings - Fork 5
SWR
The name โSWRโ is derived fromย
stale-while-revalidate
, a HTTP cache invalidation strategy popularized byย HTTP RFC 5861. SWR is a strategy to first return the data from cache (stale), then send the fetch request (revalidate), and finally come with the up-to-date data.
React Hooks for Data Fetching - SWR
์ฆ, cache
๋ก๋ถํฐ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๋ฆฌํดํ๊ณ ๊ทธ ๋ค์์ fetch
๋ฅผ ํตํด ์
๋ฐ์ดํธ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฆฌํดํ๋ ํ์์
๋๋ค.
์ด๋ฌํ ๋ก์ง์ ํตํด ์ฌ์ฉ์์๊ฒ ์กฐ๊ธ ๋ ์ข์ UX๋ฅผ ์ ๊ณตํฉ๋๋ค.
const { data, error, isValidating, mutate } = useSWR(key, fetcher, options)
-
key
: ์์ฒญ์ ์ํ ๊ณ ์ ํ ํค ๋ฌธ์์ด(๋๋ ํจ์ / ๋ฐฐ์ด / null) -
fetcher
: (์ต์ ) ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ํจ์๋ฅผ ๋ฐํํ๋ Promise -
options
: (์ต์ ) SWR hook์ ์ํ ์ต์ ๊ฐ์ฒด
-
data
:ยfetcher
๊ฐ ์ดํํ ์ฃผ์ด์ง ํค์ ๋ํ ๋ฐ์ดํฐ(๋ก๋๋์ง ์์๋ค๋ฉด undefined) -
error
:ยfetcher
๊ฐ ๋์ง ์๋ฌ(๋๋ undefined) -
isValidating
: ์์ฒญ์ด๋ ๊ฐฑ์ ๋ก๋ฉ์ ์ฌ๋ถ -
mutate(data?, shouldRevalidate?)
: ์บ์ ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฎคํ ์ดํธํ๊ธฐ ์ํ ํจ์
-
fetcher(args)
: fetcher ํจ์ -
revalidateOnFocus = true
: ์ฐฝ์ด ํฌ์ปค์ฑ๋์์ ๋ ์๋ -
revalidateOnReconnect = true
: ๋ธ๋ผ์ฐ์ ๊ฐ ๋คํธ์ํฌ ์ฐ๊ฒฐ์ ๋ค์ ์ป์์ ๋ ์๋์ผ๋ก ๊ฐฑ์ (navigator.onLine
์ ํตํด) -
refreshInterval = 0
: ์ธํฐ๋ฒ ํด๋ง(๊ธฐ๋ณธ์ ์ผ๋ก๋ ๋นํ์ฑํ) -
refreshWhenHidden = false
: ์ฐฝ์ด ๋ณด์ด์ง ์์ ๋ ํด๋ง(refreshInterval
์ด ํ์ฑํ๋ ๊ฒฝ์ฐ) -
refreshWhenOffline = false
: ๋ธ๋ผ์ฐ์ ๊ฐ ์คํ๋ผ์ธ์ผ ๋ ํด๋ง(navigator.onLine
์ ์ํด ๊ฒฐ์ ๋จ) -
shouldRetryOnError = true
: fetcher์ ์๋ฌ๊ฐ ์์ ๋ ์ฌ์๋ -
dedupingInterval = 2000
: ์ด ์๊ฐ ๋ฒ์๋ด์ ๋์ผ ํค๋ฅผ ์ฌ์ฉํ๋ ์์ฒญ ์ค๋ณต ์ ๊ฑฐ -
focusThrottleInterval = 5000
: ์ด ์๊ฐ ๋ฒ์ ๋์ ๋จ ํ ๋ฒ๋ง ๊ฐฑ์ -
errorRetryInterval = 5000
: ์๋ฌ ์ฌ์๋ ์ธํฐ๋ฒ -
errorRetryCount
: ์ต๋ ์๋ฌ ์ฌ์๋ - ๊ธฐํ ๋ฑ๋ฑ.... ๋ ๋ง๋ค.
์ฒซ๋ฒ์งธ ์ธ์๋ key์ ๋ํ ํญ๋ชฉ์ผ๋ก ๋๋ฒ์งธ ์ธ์์ธ fetcher์๊ฒ ์ ๋ฌ๋๋ ์ธ์๋ก ์ฌ์ฉ๋๋ ๊ฒ๊ณผ ๋์์ SWR ์์ฒญ์ ๊ตฌ๋ถ ์ธ์๋ก๋ ์ฌ์ฉ๋ฉ๋๋ค. ๋ณดํต URL์ ๊ฐ์ ๋ด์ฉ์ ์ ๋ฌํฉ๋๋ค.
๋๋ฒ์งธ ์ธ์๋ fetcher์ ๋ํ ํญ๋ชฉ์ผ๋ก Data๋ฅผ Fetchํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ๋ณดํต fetch๋ axios๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const fetcher = url => fetch(url).then(r => r.json())
function App () {
const { data, error } = useSWR('/api/data', fetcher)
// ...
}
๋๋ฒ์งธ ์ธ์์ธ fetcher๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ฉด ํด๋น ์๋ต์ด data๋ก ์ธํ ๋๊ณ , ์ค๋ฅ ๋ฐ์ ์ error๋ก ์ธํ ๋ฉ๋๋ค.
SWR์ ํ์ด์ง์ ๋ค์ ํฌ์ปค์คํ๊ฑฐ๋ ํญ์ ์ ํํ ๋, ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํฉ๋๋ค.
SWR์ revalidateOnFocus
์ต์
์ ํตํด ๊ฐ๋ฅํ๋ฉฐ, ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ต๋๋ค.
SWR์ refreshInterval
์ ์ด์ฉํ์ฌ ๋งค ์๊ฐ๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์
๋ฐ์ดํธ๋ฅผ ํ ์ ์์ต๋๋ค.
useSWR('/api/todos', fetcher, { refreshInterval: 1000 }) // 1์ด๋ง๋ค ์
๋ฐ์ดํธ
๊ธฐ์กด์ SWR
์ useSWR
์ ์ฌ์ฉํ์ฌ ํ์ด์ง๋ค์ด์
๋ฐ ์ธํผ๋ํฐ ๋ก๋ฉ์ ๊ตฌํํ ์ ์์ง๋ง, SWR
์์ ์ ๊ณตํด์ฃผ๋ useSWRInfinite
Hook์ ์ด์ฉํ์ฌ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ณ ์ ํฉ๋๋ค.
-
getKey
: ์ธ๋ฑ์ค์ ์ด์ ํ์ด์ง ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ณ ํ์ด์ง์ ํค๋ฅผ ๋ฐํํ๋ ํจ์ -
fetcher
:ยuseSWR
์ย fetcherํจ์์ ๋์ผ -
options
:ยuseSWR
์ด ์ง์ํ๋ ๋ชจ๋ ์ต์ ์ ๋ฐ์. ์ธ ๊ฐ์ ์ถ๊ฐ ์ต์ ์ ํฌํจ:-
initialSize = 1
: ์ด๊ธฐ์ ๋ก๋ํด์ผ ํ๋ ํ์ด์ง์ ์ -
revalidateAll = false
: ํญ์ ๋ชจ๋ ํ์ด์ง์ ๊ฐฑ์ ์๋ -
persistSize = false
: ์ฒซ ํ์ด์ง์ ํค๊ฐ ๋ณ๊ฒฝ๋ ๋, ํ์ด์ง ํฌ๊ธฐ๋ฅผ 1(initialSize
๊ฐ ์ค์ ๋ ๊ฒฝ์ฐยinitialSize
)๋ก ์ด๊ธฐํํ์ง ์์
-
-
data
: ๊ฐ ํ์ด์ง์ ๊ฐ์ ธ์ค๊ธฐ ์๋ต ๊ฐ์ ๋ฐฐ์ด -
error
:ยuseSWR
์ยerror
์ ๋์ผ -
isValidating
:ยuseSWR
์ยisValidating
๊ณผ ๋์ผ -
mutate
:ยuseSWR
์ ๋ฐ์ธ๋ฉ ๋ ๋ฎคํ ์ดํธ ํจ์์ ๋์ผํ์ง๋ง ๋ฐ์ดํฐ ๋ฐฐ์ด์ ๋ค๋ฃธ -
size
: ๊ฐ์ ธ์ฌย ํ์ด์ง ๋ฐ ๋ฐํ๋ ย ํ์ด์ง์ ์ -
setSize
: ๊ฐ์ ธ์์ผ ํ๋ ํ์ด์ง์ ์๋ฅผ ์ค์
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null // ๋์ ๋๋ฌ
return `/users?page=${pageIndex}&limit=10` // SWR ํค
}
function App () {
const { data, size, setSize } = useSWRInfinite(getKey, fetcher)
if (!data) return 'loading'
return <div>
{data.map((users, index) => {
// `data`๋ ๊ฐ ํ์ด์ง์ API ์๋ต ๋ฐฐ์ด์
๋๋ค.
return users.map(user => <div key={user.id}>{user.name}</div>)
})}
<button onClick={() => setSize(size + 1)}>Load More</button>
</div>
}
๊ธฐ์กด์ useSWR๊ณผ useSWRInfinite ๊ฐ์ฅ ํฌ๊ฒ ๋ค๋ฅธ ์ ์ getKey ํจ์
์ ๋ฐํ๋๋ data์ ํํ
์ด๋ค.
getKey ํจ์
๊ฐ ํ์ฌ ํ์ด์ง์ ์ธ๋ฑ์ค์ ์ด์ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ์ธ์๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ useSWR์ ๋ณด๋ค ์ธ๋ฑ์ค ๊ธฐ๋ฐ ๋ฐ ์ปค์ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์
์ ์ฝ๊ฒ ์ง์ํ ์ ์์ต๋๋ค.
๋ํ ์๋ต๋ฐ๋ data๊ฐ ํ๋์ API ์๋ต์ด ์๋ ์ฌ๋ฌ API์ ์๋ต์ ๋ฐฐ์ด ํํ์ ๋๋ค.
// ex) ๋ฐํ๋๋ data ํํ => 2์ฐจ์ ๋ฐฐ์ด
[
[
{ name: 'Alice', ... },
{ name: 'Bob', ... },
{ name: 'Cathy', ... },
...
],
[
{ name: 'John', ... },
{ name: 'Paul', ... },
{ name: 'George', ... },
...
],
...
]
- IntersectionObserver
- B-Tree
- Web Server & Web Application Server
- Query Optimization (1)
- Query Optimization (2)
- M1 Mac์์ link preview generator ์ค์น ์ค ๋ฐ์ํ๋ ์ค๋ฅ
- CORS
- react-router-dom
- Artillery: Performance testing tool
- JWT
- LinkPreview
- SWR
- ์ฟผ๋ฆฌ์ฑ๋ฅํฅ์&๋ฌดํ์คํฌ๋กค
- 10์ 26์ผ ํ์์ผ
- 10์ 27์ผ ์์์ผ
- 10์ 28์ผ ๋ชฉ์์ผ
- 11์ 1์ผ ์์์ผ
- 11์ 2์ผ ํ์์ผ
- 11์ 3์ผ ์์์ผ
- 11์ 4์ผ ๋ชฉ์์ผ
- 11์ 9์ผ ํ์์ผ
- 11์ 10์ผ ์์์ผ
- 11์ 11์ผ ๋ชฉ์์ผ
- 11์ 16์ผ ํ์์ผ
- 11์ 17์ผ ์์์ผ
- 11์ 18์ผ ๋ชฉ์์ผ
- 11์ 23์ผ ํ์์ผ
- 11์ 24์ผ ์์์ผ
- 11์ 25์ผ ๋ชฉ์์ผ
- 11์ 30์ผ ํ์์ผ
- 12์ 1์ผ ์์์ผ
- 12์ 2์ผ ๋ชฉ์์ผ