S(stail) W(while) R(revalidate) = 처음 캐시로부터 데이터를 가져오고(stale), fetch요청을 보내 revalidating하여 최신 데이터를 유지한다.Data Fetching 라이브러리) 💦 SWR 진행 과정
(1) 먼저 캐시(stale, 스태일)로부터 데이터를 반환한 후 (=cache로 부터 받아온 데이터 즉, 오래된 정보를 먼저 return)
(2) fetch 요청(재검증)을 하고 (=서버에서 데이터 가져오기)
(3) 최종적으로 최신화된 데이터를 가져오는 전략 (=재검증, 마지막으로 최신 데이터 가져오기)
💦 SWR 의 특징
Lightweight : 가벼움.Realtime : 자동으로 데이터 업데이트. (실시간 경험)Suspense : 항상 빠르고 반응적.Pagination : 쪽수 매기기Backend Agnostic : Backend에 의존하지 않음.SSR / ISR / SSG 지원 TypeScript Ready💦 useSWR(첫 번째 인자[key], 두 번째 인자[fetcher](fetch로 받아온 url)) ⭐️⭐️⭐️
{ data, error } = useSWR(key, fetcher)
keyfetcher(1) useSWR 의 첫번째 인자인 key 값을 기준으로 중복 요청을 제거하고, 캐시를 하며, 해당 값을 마치 전역 상태관리처럼 share 까지 해준다.
(2) useSWR 의 두번째 인자인 fetcher 은 SWR 내부적으로 구현되어있는 것이 아니라 사용자가 직접 정의하는 것이다. 때문에 fetch, axios 던 문제 없이 사용 가능하다.
dataerror일반적으로 parent 컴포넌트 에서 data fetch 를 실행한 후 child 컴포넌트 에 props 로 전달하는 형태로 로직이 구성된다.
(만약 전역상태를 관리한다면 fetch 만 top level 에서 하고 child 컴포넌트에서는 주로 사용하는 형태.)
SWR 에서는 사용하는 곳에서 바로 data fetch 를 실행함과 동시에 로컬 스테이트를 정의할 수 있다.
// 기존 fetch로 data를 받아오는 경우---------- // 부모 component에서 데이터를 fetch한다. function Page () { const [user, setUser] = useState(null) // fetch data useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(data => setUser(data)) }, []) // global loading state if (!user) { return <Spinner/> } return ( <div> // 자식 컴포넌트로 props넘겨준다 <Avatar user={user} /> <Content user={user} /> </div> ) } // child components function Content ({ user }) { return <h1>Welcome back, {user.name}</h1> } function Avatar ({ user }) { return <img src={user.avatar} alt={user.name} /> } ------------------------------------------------------ // useSWR 로 data를 받아오는 경우---------- ❗️ 단 한번의 API request 만 있다. function useUser (id) { const { data, error } = useSWR(`/api/user/${id}`, fetcher) // API 데이터를 받아와서 각 user, isLoading, isError 에 객체 형태로 담아준다(각 컴포넌트에서 활용) return { user: data, isLoading: !error && !data, // !error && !data를 이용해 로딩 상태도 관리할 수 있다 isError: error } } function Page () { return <div> <Avatar /> <Content /> </div> } // child components function Content () { const { user, isLoading } = useUser() if (isLoading) { return <Spinner /> } return <h1>Welcome back, {user.name}</h1> } function Avatar () { const { user, isLoading } = useUser() if (isLoading) { return <Spinner /> } return <img src={user.avatar} alt={user.name} /> }
🌈 http 요청을 통해 서버에서 데이터를 받아오는 방식으로는
Fetch API,Axios(Ajax API 통신용라이브러리) 등이 있다. 그러나 일단 작업이 완료되면 데이터를 캐시하거나 페이지를 매김하는 데 도움이 되지 않으므로 직접 처리해야 한다.
SWR은 캐싱, 페이지매김, 스크롤위치 복구, 종속 페치 등과 같은 기능들이 포함되어 있기 때문에 더욱 편리하다. 뿐만아니라 데이터가 항상 최신 상태인지 확인하기 위해 SWR은 네트워크가 복구 될 때 자동으로 재 검증해주기 때문에 자동 업데이트가 된다는 강력한 장점이 있다.
- 데이터 fetch가 데이터가 필요한 컴포넌트에 바인딩되고, 모든 구성 요소가 서로 독립적이다.
- 상위 컴포넌트는 데이터 혹은 전달에 대해 알 필요가 없어진다.
- 동일한 SWR Key를 사용하면, 자동으로 중복 요청이 제거 되고, 요청이 캐시 되고 공유된다.
즉, API 요청이 1 개만 전송 된다는 것이다.
fetch()메서드를 사용한다. Headers, Request, Response 이다. 이는 곧 HTTP의 개념과 대응되는 Interface이다.💦 fetch API 의 특징

💦 fetch API 의 사용법
fetch(url, options) .then((response) => {response.json()}) .then((data) => {console.log(data)}) .catch((error) => {console.log("error:", error)})첫번째 인자로 URL, 두번째 인자로 옵션 객체를 받게된다.
그래서, Promise 타입의 객체를 반환하게 되는데, 이 반환되어진 객체는, API 호출이 성공했을 경우에는 응답(response) 객체를 resolve하고, 실패했을 경우에는 예외(error) 객체를 reject하게된다.옵션객체(options)는 HTTP 방식(method) / HTTP 요청헤더(headers) / HTTP 전문(body) 등을 설정이 가능하다.
그리고, 응답객체로 부터는 HTTP 응답상태(status), HTTP 응답헤더(headers), HTTP 응답전문(body) 등을 읽어올 수 있다.
❗️
fetch()메서드는 가져오려는 데이터(resource)의 경로인 하나의 필수 인수를 사용한다.fetch('http://example.com/fetch') // 하나의 필수 인수 = 데이터 경로 .then((res) => { res.json() }) // json으로 변환 .then((data) => { console.log('success :',data); }) // 성공적으로 받아왔을때 .catch((error) => { console.log('error :', error); }); // 실패했을때서버 응답이 HTTP오류 상태인 경우에도 서버가 헤더로 응답하는 즉시 해당 요청으로 Promise를 반환한다. (즉, 비동기로 성공적으로 데이터를 받아올 수 있으나, error인 경우에는 Promise객체를 반환하여 보여준다)
선택적으로 두 번째 인수로 options 객체를 전달할 수도 있다.
💦 fetch API 의 options에 request 적용
🌱 Request 설정 옵션
method: 사용할 메소드를 선택 (GET, POST, PUT, DELETE 등등)
headers: 헤더에 전달할 값
body: 바디에 전달할 값
mode: cors 등의 값을 설정 (cors, no-cors, same-origin)
cache: 캐쉬 사용 여부 (no-cache, reload, force-cache, only-if-cached)
credentials: 자격 증명을 위한 옵션 설정(include, same-origin, omit) (Default. same-origin)
fetch(url, { // options에 설정 값들을 객체 형태로 넣어준다. method: 'GET', headers: { 'Content-Type': 'application/json' }, 'mode': 'cors' }) .then((response) => { response.json() }) .then(data => { console.log('success :',data); }) .catch((error) => { console.log(error) }); // 또는 아래와 같이 설정값들만 따로 모아 하나의 객체 변수에 저장할 수 있다 let optObj = { method: "GET", headers: { 'Content-Type': 'application/json' }, 'mode': 'cors' }; fetch(url, optObj) .then((res) => { res.json() }) .then(data => { return data }) .catch(error => { console.log(error) }) // 데이터를 전송(POST)하는 경우에는 // body에 JSON.stringify()로 변환하여 값을 추가한다 fetch(url, { method: 'POST', body: JSON.stringify({ sitename: 'webisfree' }) }) .then(function(response) { //... }); ❗️ Fetch API에서는 직접 JSON.stringify()를 사용하여 JSON 타입의 문자열로 변환해야 한다.
