์ผ๋ฐ์ ์ธ pagenation์ ๊ฐ๋จํ ์ค๋ช ํ๊ณ , useSWRInfinite์ ๋ํด ์๊ฐํ๊ณ ์ ํฉ๋๋ค.
https://swr.vercel.app/ko/docs/pagination
Pagination
๊ธฐ๋ณธ pagination์ useSWRInfinite๋ฅผ ํ์๋ก ํ์ง ์์ต๋๋ค.
function Page ({ index }) {
const { data } = useSWR(`/api/data?page=${index}`, fetcher);
// ... ๋ก๋ฉ ๋ฐ ์๋ฌ ์ํ๋ฅผ ์ฒ๋ฆฌ
return data.map(item => <div key={item.id}>{item.name}</div>)
}
function App () {
const [pageIndex, setPageIndex] = useState(0);
return <div>
<Page index={pageIndex}/>
<div style={{ display: 'none' }}><Page index={pageIndex + 1}/></div>
<button onClick={() => setPageIndex(pageIndex - 1)}>Previous</button>
<button onClick={() => setPageIndex(pageIndex + 1)}>Next</button>
</div>
}
๊ฐ๋จํ๊ฒ useSWR์ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ๋ฐ๋ณต๋ฌธ์ ๋๋ ค divํ๊ทธ๋ฅผ ์๋ก ์ถ๊ฐํ๊ฒ ๋ฉ๋๋ค.
api ์ฃผ์๋ง ๋ง์ถ๋ฉด, ํฐ ๋ฌด๋ฆฌ ์์ด ์ธ์ ์ด๋์๋ ์์ฑํ ์ ์์ ๋ฒํ ์ฝ๋์ ๋๋ค.
display : 'none'์ ์ถ๊ฐํด์ SWR์ ์บ์ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ํ๋ฆฌ๋ก๋ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค๊ณ ๊ณตํ์์ ์๊ฐํด์ฃผ๋๋ฐ,
๋ฏธ๋ฆฌ ๊ทธ๋ ค๋๊ณ ๋ฐ๊ฟ์ฃผ๋ฉด ์๋ ์ธก๋ฉด์์ ์ข์ ๋ณด์ ๋๋ค.
Infinite Scroll
์ด ๊ธ์ ๋ชฉ์ ์ ํด๋น ๊ธฐ๋ฅ์ ์ค๋ช ํ๊ณ ์ถ์ด์์์ต๋๋ค.
๋ฌดํ ์คํฌ๋กค๋ก ์คํฌ๋กค์ด ๋์์ด ๋ด๋ ค๊ฐ๋ ๊ธฐ๋ฅ์ ๋งํฉ๋๋ค.
import useSWRInfinite from 'swr/infinite'
const { data, error, isLoading, isValidating, mutate, size, setSize } = useSWRInfinite(
getKey, fetcher?, options?
)
parameter
- getKey : index์ ์ด์ ํ์ด์ง ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ณ ํ์ด์ง์ ํค๋ฅผ ๋ฐํํ๋ ํจ์
- fetcher : useSWR๊ณผ ๋์ผ
- option : useSWR๊ณผ ๋์ผํ๋ฉฐ, ๋ช ๊ฐ์ง ์ถ๊ฐ๋์ต๋๋ค. ๊ณตํ์์ ํ์ธํ์๋ฉด ๋ฉ๋๋ค.
return
- data : fetcher์์ ์ฑ๊ณต์ ์ผ๋ก ํต์ ์ ํ์ ๋ ๋ฆฌํด๋๋ ๊ฐ
- size : ๊ฐ์ ธ์ฌ ํ์ด์ง ๋ฐ ๋ฐํ๋ ํ์ด์ง ์ (state๊ฐ)
- setSize : ๊ฐ์ ธ์์ผ ํ๋ ํ์ด์ง์ ์
- error, isLoading, isValidating, mutate๋ useSWR๊ณผ ๋์ผ
์
const getKey = (pageIndex, previousPageData) => {
if (previousPageData && !previousPageData.length) return null
return `/users?page=${pageIndex}&limit=10`
}
function App () {
const { data, size, setSize } = useSWRInfinite(getKey, fetcher)
if (!data) return 'loading'
return <div>
<p>users listed</p>
{data.map((users, index) => {
return users.map(user => <div key={user.id}>{user.name}</div>)
})}
<button onClick={() => setSize(size + 1)}>Load More</button>
</div>
}
getKey ํจ์๋ฅผ ๋ง๋ค์ด์ useSWR์ฒ๋ผ key๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค. ๋์ ๋๋ฌํ์ผ๋ฉด null๋ก ๋ฃ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
useSWR์ด๋ ์ฌ์ฉํ๋ ๋ฐ๋ ํฐ ์ฐจ์ด๊ฐ ์์ด ๋ณด์ ๋๋ค.
๋์ ์๋ฆฌ๋ฅผ ์ค๋ช ๋๋ฆฌ์๋ฉด,
- getKey๊ฐ ์คํ๋์ด ์ฒซ ํ์ด์ง pageIndex ๊ฐ์ด 0์ผ๋ก returnํ๊ฒ ๋ฉ๋๋ค.
- return ๋ key๊ฐ์ผ๋ก fetcher๊ฐ ์คํ๋์ด ๋ฆฌํด๊ฐ์ด data์ ์ ์ฅ๋ฉ๋๋ค.
- Load More๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ค์ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
- setSize๋ฅผ ํตํด size๊ฐ์ด +1๋์ต๋๋ค.
- size๋ state๊ฐ์ด๊ธฐ ๋๋ฌธ์ ํ๋ฉด์ด ๋ฆฌ๋ ๋๋ง ๋๊ณ , useSWRInfinite๊ฐ ์คํ๋ฉ๋๋ค.
- ๊ทธ๋ฌ๋ฉด์ getKeyํจ์๊ฐ ๋ค์ ์คํ์ด๋๊ณ , size๋ pageIndex์ ์ธ์๊ฐ์ผ๋ก ๋ค์ด๊ฐ๊ฒ๋ฉ๋๋ค.
- ๋ ๋ฒ์งธ ํ์ด์ง์ ๋ฆฌํด๊ฐ๋ค์ด data์ ๋์ ๋์ด ์์ด๊ฒ ๋๊ณ , ํ๋ฉด์ด ๊ทธ๋ ค์ง๊ฒ ๋ฉ๋๋ค.
Global Mutate
import { useSWRConfig } from "swr"
import { unstable_serialize } from "swr/infinite"
function App() {
const { mutate } = useSWRConfig()
mutate(unstable_serialize(getKey))
}
binding mutate๋ useSWR๊ณผ ๋์ผํ๊ฒ ์ฌ์ฉํ๋ฉด ๋๊ณ , global๋ง ๋ฐฉ์์ด ์กฐ๊ธ ๋ฌ๋ผ ์ถ๊ฐํ์์ต๋๋ค.
SWR์ ์ด ์ ๋๋ฉด ํ์ํ ๊ฒ๋ค์ ์ค๋ช ํ ๊ฑฐ ๊ฐ์ต๋๋ค.
์ถ๊ฐ๋ก ์ฌ์ฉํ๊ฑฐ๋ ํ์ํด ๋ณด์ด๋ ๊ฒ๋ค์ ์ถ๊ฐ๋ ์๋ ์์ ๋ฏ์ถ๊ธด ํฉ๋๋ค.
SWR์ด๋ React-Query๋ ์ ์ผ ๋ง์ด ๋น๊ต๋๋๋ฐ,
React-Query๋ฅผ ์ฌ์ฉํด๋ณด์ง๋ ์์์ง๋ง, ์ฌ์ฉ๋ฒ์ด๋ ๊ฐ๋ ์ ๋น์ทํด ๋ณด์ ๋๋ค.
SWR๋ณด๋ค๋ React-Query๊ฐ ๋ค์ด๋ก๋์๊ฐ ๋ง๊ธฐ ํ๋ ํ๋ฐ, ๋ค์ด๋ก๋ ์๊ฐ ๋น์ทํด์ง ๊ฑฐ ๋ด์๋ ๋ ์ค์ ํ๋๋ง ์ ์จ๋
๋ฌธ์ ์์ด ๊ฐ๋ฐํ ์ ์์ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
'Front-End > Library' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Library] swagger-ui-react (0) | 2023.07.07 |
---|---|
Library] SWR : ์์ฉ_Mutate & Revalidation (0) | 2023.07.03 |
Library] SWR : ์์ฉ (0) | 2023.07.03 |
Library] SWR (0) | 2023.07.03 |
Library] Swiper (0) | 2023.06.29 |