노트

useSyncExternalStore

useSyncExternalStore

프런트엔드#react · 연결된 개념 6개

쉽게 말하면

useSyncExternalStore는 React 밖에 있는 값을 구독해서, 한 번 렌더하는 동안 모든 컴포넌트가 같은 순간의 값을 보게 하는 훅이에요. 단체 사진을 찍을 때 모두가 같은 순간에 찍히도록 셔터를 맞추는 셈이죠.

비유가 깨지는 곳 셔터 직전에 값이 바뀌었으면 React는 렌더 결과를 버리고 다시 찍어요. 그래서 getSnapshot은 값이 그대로면 같은 참조를 돌려줘야 하고, 매번 새 객체를 만들면 무한 렌더가 돼요.

useSyncExternalStore는 React 밖에 있는 상태(외부 스토어(External Store), 브라우저 API(Application Programming Interface))를 구독해 컴포넌트와 동기화하는 훅이다. 동시성 렌더링(Concurrent Rendering)에서도 모든 컴포넌트가 같은 스냅샷을 보게 보장해 상태 찢어짐(Tearing)을 막는다(React 18+).

function subscribe(callback) {
  window.addEventListener('online', callback)
  window.addEventListener('offline', callback)
  return () => {
    window.removeEventListener('online', callback)
    window.removeEventListener('offline', callback)
  }
}
const isOnline = useSyncExternalStore(
  subscribe,                // 변경 알림 등록, 해제 함수 반환
  () => navigator.onLine,   // getSnapshot: 현재 값
  () => true,               // getServerSnapshot: SSR·하이드레이션용
)
  • React는 렌더할 때 getSnapshot()을 읽고, 커밋 직전에 다시 읽어 값이 달라졌으면 렌더 결과를 버리고 다시 렌더한다
  • getSnapshot은 값이 그대로면 같은 참조를 돌려줘야 한다. 매번 새 객체를 만들면 계속 바뀐 것으로 보여 무한 렌더가 된다
  • subscribe는 컴포넌트 밖에 두거나 고정해야 렌더마다 재구독하지 않는다
  • 브라우저 쪽 예: 온라인 상태, 창 크기, 다른 탭에서 바뀐 localStorage(storage 이벤트, localStorage와 sessionStorage)
  • 직접 쓸 일은 많지 않다. react-redux 8 이상, Zustand 4 이상 같은 상태 라이브러리가 내부에서 이 훅으로 스토어를 연결한다(Redux 이후의 상태 관리 선택)
  • 구독과 알림 구조는 옵저버 패턴 그대로다

출처: React - useSyncExternalStore

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • React 서버 컴포넌트(RSC)

    React 서버 컴포넌트(React Server Components, RSC)는 서버에서만 실행되고, 컴포넌트 코드가 아니라 실행 결과(직렬화된 엘리먼트 트리)만 클라이언트로 보내는 컴포넌트다. Next.js App Router에서는 'use client'를 붙이지 않은 컴포넌트가 기본으로 서버 컴포넌트다.

  • Suspense

    Suspense는 아직 준비되지 않은 하위 트리의 렌더를 잠시 보류(suspend)하고, 그동안 가장 가까운 경계의 fallback을 보여 주는 React의 비동기 렌더링 메커니즘이다. 로딩 상태를 컴포넌트마다 들고 있지 않고 경계에 위임한다.

  • useEffectEvent

    useEffectEvent는 Effect 안에서 부르되 의존성 배열(Dependency Array)에는 넣지 않는 이벤트 함수를 만드는 훅이다. 항상 최신 props·state를 읽지만, 그 값이 바뀐다고 Effect가 다시 실행되지는 않는다. React 19.2에서 정식이 됐다(2026 기준).

  • Effect가 필요 없는 경우

    Effect는 외부 시스템과 동기화할 때 쓰는 탈출구(Escape Hatch)다. 렌더 중에 계산할 수 있는 값이나 사용자 이벤트 처리에 Effect를 쓰면 렌더가 한 번 더 일어나고 흐름이 꼬인다. React 공식 문서가 이런 경우를 따로 정리해 두었다.

  • React의 규칙과 렌더 순수성

    Rules of React는 React가 올바르게 동작하고 최적화하기 위해 코드가 지켜야 하는 규칙으로, 공식 문서가 세 가지로 정리한다. 핵심은 렌더가 순수한 계산이어야 한다는 것이다.

보기 옵션