리액트 팀이 만들었던 useFetch 프로토타입은 커스텀 훅의 가능성을 보여주는 훌륭한 예제였지만, 실제 프로덕션 환경에서 사용하기에는 부족한 점이 많았다. 캐싱 전략도, 데이터를 자동으로 최신 상태로 유지하는 기능도 없었다.
이때, Vercel(과거 Zeit) 팀의 핵심 개발자들, 기예르모 라우치(Guillermo Rauch)와 쇼 우에스기(Shu Uesugi)가 SWR이라는 이름의 새로운 데이터 패칭 라이브러리를 공개했다.
SWR은 Stale-While-Revalidate의 약자였다.
이름 자체가 라이브러리의 핵심 전략을 담고 있었다.
‘일단 오래된(Stale) 데이터라도 캐시에서 꺼내 화면에 보여주고, 그 사이에 백그라운드에서 데이터를 재검증(Revalidate)하여 최신 정보로 업데이트한다.’
이 전략은 사용자 경험을 극적으로 향상시켰다. 사용자는 더 이상 빈 로딩 화면을 멍하니 쳐다보지 않아도 되었다. 일단 이전에 봤던 내용이라도 즉시 화면에 나타나고, 잠시 후에 자연스럽게 최신 내용으로 바뀌는 것이다.
그리고 이 모든 마법의 중심에는 useSWR이라는 단 하나의 훅이 있었다.
한 개발자가 SWR을 사용하여 뉴스피드를 만드는 코드를 시연했다.
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
function NewsFeed() {
const { data, error } = useSWR('/api/news', fetcher);
if (error) return <div>failed to load</div>;
if (!data) return <div>loading...</div>;
return (
<ul>
{data.articles.map((article) => (
<li key={article.id}>{article.title}</li>
))}
</ul>
);
}
여기까지는 useFetch와 비슷해 보였다.
하지만 SWR의 진정한 힘은 보이지 않는 곳에서 발휘되었다.
개발자가 시연을 이어갔다.
그는 뉴스피드가 보이는 브라우저 탭을 잠시 벗어나 다른 탭을 클릭했다가, 다시 뉴스피드 탭으로 돌아왔다.
그 순간, 놀라운 일이 일어났다.
개발자 도구의 네트워크 탭에 /api/news 요청이 자동으로 다시 발생하는 것이 보였다. useSWR 훅이 ‘사용자가 화면에 다시 집중하고 있다’는 것을 감지하고, 데이터가 그 사이에 변경되었을 가능성에 대비해 자동으로 재검증을 시작한 것이다. 만약 서버에 새로운 뉴스가 추가되었다면, 화면은 별도의 코드 없이도 자연스럽게 업데이트될 터였다.
이것이 끝이 아니었다.
SWR은 기본적으로 다음과 같은 상황에서 자동으로 데이터를 재검증했다.
- 컴포넌트가 마운트될 때
- 브라우저 창에 포커스가 돌아올 때
- 네트워크 연결이 끊겼다가 다시 연결될 때
- 설정된 시간 간격(interval)에 따라 주기적으로
데이터는 더 이상 개발자가 수동으로 ‘가져오는’ 정적인 존재가 아니었다.
useSWR을 통해, 데이터는 스스로 자신의 생명력을 가지고, 주변 환경의 변화에 반응하여 살아 숨 쉬는 동적인 존재가 되었다.
이것은 데이터 패칭에 대한 멘탈 모델을 완전히 바꾸는 것이었다.
개발자는 더 이상 ‘언제’ 데이터를 가져올지 고민할 필요가 없었다. 그저 useSWR을 통해 필요한 데이터를 ‘선언’하기만 하면, 라이브러리가 최적의 전략으로 데이터의 ‘생명주기’ 전체를 관리해주었다.
댄과 리액트 팀은 SWR과 react-query 같은 라이브러리들의 등장을 보며, 훅이 가진 진정한 잠재력을 다시 한번 확인했다. 훅은 단순히 코드를 재사용하는 도구를 넘어, 애플리케이션의 복잡한 비동기 로직을 추상화하고, 개발자가 더 높은 차원에서 문제를 바라볼 수 있도록 돕는 강력한 ‘패러다임’ 그 자체였다.
생태계는 훅이라는 새로운 언어를 통해, 스스로 진화하고 있었다.


