브라우저와 대화하는 가장 쉬운 방법 (react-use)

802025년 11월 03일3

훅의 시대가 열리면서, 개발자들은 리액트 컴포넌트와 브라우저 자체의 기능(Web API)을 연동하는 방식에 대해 다시 생각하기 시작했다.

과거에는 window.addEventListener를 사용해 스크롤 이벤트를 감지하거나, navigator.geolocation으로 사용자의 위치를 가져오거나, document.visibilityState로 페이지가 활성화 상태인지 확인하는 등의 작업을 하려면, 클래스의 생명주기 메서드 안에서 번거로운 설정과 정리 로직을 직접 구현해야만 했다.

이러한 반복적이고 오류가 발생하기 쉬운 작업들을 해결하기 위해, 커뮤니티에서는 범용적인 커스텀 훅들을 모아놓은 거대한 라이브러리가 등장하기 시작했다. 그중 가장 대표적인 것이 바로 react-use였다.

react-use는 마치 웹 개발을 위한 ‘스위스 군용 칼’과도 같았다.
배터리 상태, 네트워크 연결 상태, 화면 방향, 마우스 위치, 심지어 사용자의 장치가 유휴 상태인지 여부까지, 상상할 수 있는 거의 모든 브라우저 API를 간결한 커스텀 훅으로 추상화해 놓았다.

한 개발팀이 사용자가 스크롤을 내려 특정 이미지가 화면에 보일 때, 부드럽게 나타나는 애니메이션을 구현하는 과제를 받았다.
이를 위해서는 Intersection Observer라는, 비교적 최신의 강력하지만 설정이 복잡한 Web API를 사용해야 했다. useEffect 안에서 Observer 인스턴스를 생성하고, 타겟 요소를 관찰하고, 컴포넌트가 언마운트될 때 관찰을 멈추는 모든 과정을 직접 관리해야 했다.

이때, 한 개발자가 react-use 라이브러리를 가져왔다.
그리고 그 안의 useIntersection 훅을 사용했다.

import { useIntersection } from 'react-use';
import { useRef } from 'react';

function FadeInImage({ src, alt }) {
  const intersectionRef = useRef(null);
  
  // useIntersection 훅을 사용하여, ref가 연결된 요소의 관찰 정보를 가져온다.
  const intersection = useIntersection(intersectionRef, {
    root: null,
    threshold: 0.5, // 요소가 50% 이상 보일 때 감지
  });

  const isVisible = intersection && intersection.isIntersecting;

  return (
    <img 
      ref={intersectionRef} 
      src={src} 
      alt={alt}
      style={{
        transition: 'opacity 0.5s',
        opacity: isVisible ? 1 : 0,
      }}
    />
  );
}

복잡했던 Intersection Observer의 설정 과정이 완전히 사라졌다.
useIntersection 훅은 useRef로 참조된 요소가 화면에 나타났는지(isIntersecting) 여부를 알려주는, 간단한 객체를 반환했다. 개발자는 그저 이 isVisible 값에 따라 스타일을 변경해주기만 하면 되었다.

react-use 라이브러리는 이처럼 수십 개의 강력한 훅을 제공했다.

  • useLocation: 사용자의 지리적 위치(geolocation) 정보를 추적한다.
  • useNetworkState: 온라인/오프라인 상태와 연결 속도 등의 정보를 제공한다.
  • useBattery: 장치의 배터리 충전 상태와 잔량을 알려준다.
  • useLocalStorage: useLocalStorage와 동일한 기능을 수행한다.

이 라이브러리의 등장은 훅 패러다임의 중요한 가치를 다시 한번 증명했다.
훅은 브라우저가 제공하는 저수준(low-level)의 명령적인 API들을, 리액트 개발자가 사용하기 쉬운 고수준(high-level)의 선언적인 ‘부품’으로 완벽하게 변환시켰다.

개발자들은 더 이상 모든 프로젝트마다 브라우저 API 문서를 뒤적이며 보일러플레이트 코드를 작성할 필요가 없었다. 그들은 이제 react-use와 같은 라이브러리에서 필요한 훅을 찾아, 마치 레고 블록을 조립하듯 원하는 기능을 쉽고 빠르게 구현할 수 있게 되었다.

브라우저와 대화하는 방식이 근본적으로 바뀌고 있었다.
훅은 리액트와 브라우저 사이의 간극을 메우는 가장 우아하고 강력한 다리가 되어주고 있었다. 그리고 이 다리 위에서, 개발자들은 UI의 기능과 표현을 완전히 분리하는, 더 진보된 아키텍처를 꿈꾸기 시작했다.