Data fetching library
*SWR을 살펴보기 이전에 Data fetching library가 무엇인지 알아봅시다.
2020년부터 React Query 나 SWR 와 같은 data fetching 라이브러리들이 인기를 끌고 있습니다.
1년 동안 받은 깃헙 스타 개수를 기반으로 인기 지수를 측정하는 risingstars의 React Ecosystem을 확인하면 React Query가 9위, SWR이 14위(2023년 기준)로, 여전히 인기를 유지하고 있습니다.
Data fetchng library 왜 사용할까요?
이는 우선, 리액트 프로젝트에서 일반적으로 사용하는 상태(state)에 대해 알아보아야 합니다.
- Local State: 리액트 컴포넌트 안에서만 사용되는 state
- Global State: Global Store에 정의되어 프로젝트 어디에서나 접근할 수 있는 state(Redux, mobx, etc…)
- Server State: 서버로 부터 받아오는 state
예전에는 리덕스와 같은 상태 관리 라이브러리에 Global State와 Server State를 전부 포함하여 프로그래밍을 했습니다.
data fetching library를 사용하게 되면서 상태 관리 라이브러리에서 비동기 로직을 포함할 필요가 없게 되었습니다.
SWR이란?
SWR은 vercel 에서 만든 Data fetching library입니다.
Server State를 가져와서 리액트 컴포넌트에서 사용할 수 있게 합니다.
import useSWR from 'swr'
function Point(){
const {data,isLoading, error} = useSWR('/api/points', url => {
return fetch(url).then(res => res.json())
})
if(error){
return <div>failed to load</div>
}
if(isLoading){
return <div>Loading..</div>
}
return <div>{data}</div>
}
useSWR
arguments
- 첫번째 인자는 Server State에 대한 key를 받습니다.
- key는 두번째 인자인 fetcher 함수의 인자인 url로 들어갑니다.
return
- data: response data
- loading: data loading
- error: response error
주요 기능
- 한번 fetch된 Server State를 캐싱하고, 다른 컴포넌트에서 동일한 상태를 사용할 경우 캐싱된 상태를 그대로 리턴해 줍니다.
→ 별도의 프로그래밍 없이 컴포넌트 간 동일한 상태를 공유할 수 있습니다. - 지속적으로 데이터를 폴링합니다.
*폴링: 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 송수신 등의 자료처리를 하는 방식
- 폴링 타이밍
- 뷰포트 focus가 off에서 on이 되었을 때
- 네트워크가 offline에서 online이 되었을 때
- refeshInterval 설정 시 설정 시간마다
- 설정한 변수에 따라 동적으로
- 폴링 타이밍
- 커스텀 훅으로 정의하여 로컬 상태를 다루듯 사용할 수 있습니다.
// useUsers.js
import useSWR from 'swr'
export default () => {
const {data, mutate, isLoading, error} = useSWR('/api/users', url => {
return fetch(url).then(res => res.json())
})
return {data, mutate, isLoading, error}
}
mutate
- SWR 의 데이터갱신을 수정 즉시 화면에 변경된 데이터가 보여지게 하려면 mutate 함수를 이용할 수 있습니다.
mutate 함수가 호출되면 해당 상태를 즉시 다시 fetch 하고 데이터를 갱신합니다.
*refetching해야 갱신된 data가 반영됩니다.
function UserInfo(){
const {data, error, mutate} = useUsers()
const handleChange = async (user) => {
await updateUser(user)
mutate()
}
return <div>...</div>
}
refetching 없이 응답이 성공한다는 가정하에 캐시만 미리 값을 변경할 수도 있습니다.(Optimistic UI)
const handleChange = async (user) => {
await updateUser(user)
mutate(user, false)
}
Redux → SWR 대체할 수 있을까?
Redux 를 대체할 수 있는 이유가 있다면 컴포넌트간 전역 상태를 공유할 수 있다는 특성 때문입니다.
SWR은 Data fetching에 초점을 둔 라이브러리입니다.
그렇다고 로컬 상태를 관리가 불가능한 것은 아닙니다.
function useCounter(){
const {data, mutate} = useSWR('state', () => window.count)
return {data, mutate: (count) => {
window.count = count
return mutate()
}}
}
window에 count 변수를 담았지만, 다소 부자연스럽고 억지스러운 부분이 있습니다.
Redux와 SWR은 해결하고자 하는 문제가 다릅니다.
로컬 상태가 많아서 관리가 필요한 경우에는 Redux를 결합하여 사용하되, Data fetching에 대한 기능들은 SWR에 위임하는 것이 옳다는 결론입니다.
[참고자료]
'React' 카테고리의 다른 글
| React 18 주요 변경점 (0) | 2024.04.15 |
|---|---|
| 검색 기능 구현 시 고려사항(API 호출 시점, debouncing) (0) | 2024.04.15 |
| Redux → SWR(1): Redux의 한계 (1) | 2024.04.13 |
| 컴포넌트 라이프사이클 (0) | 2024.04.12 |
| Flux 아키텍쳐 (0) | 2024.04.11 |