React 10년 회고: 데이터 패칭·상태 관리·RSC·Sync Engine까지 완전 정리 ("Lessons from 10 years of React")

okorion·2025년 12월 3일

1. 핵심 요약

  • React의 10년은 데이터 패칭 전략의 반복적 진화 과정이었다.
  • 컴포넌트 클래스 → useEffect → 커스텀 훅 → React Query → Suspense → React Server Components → Sync Engine까지 패러다임 변화.
  • 상태 관리의 90%는 “서버에서 가져오는 Remote State” 문제이며, 이를 해결하면 React 개발 난이도가 크게 낮아진다.
  • 런타임 검증(Zod), 에러 경계(ErrorBoundary), URL 상태 활용, 파생 상태(Derived State) 등 실무 필수 개념 강조.
  • React 19는 “개발자들이 실제로 해온 방식”을 공식 기능으로 편입(카우패스 포장).
  • 미래 트렌드 핵심은 Sync Engine(Local-first, 실시간 동기화, 오프라인 우선)

2. React 데이터 패칭의 10년 진화 (Why)

⬛ 2015: 클래스 + componentDidMount

  • fetch를 라이프사이클에서 직접 호출
  • 로딩/에러/데이터 상태를 직접 관리
  • 에러 바운더리로 async 예외를 못 잡음
    → 초기 React의 가장 큰 단점

⬛ 2019: Hooks 직후 — useEffect의 혼란

  • dependency array, async 함수 금지, 누락된 cleanup 등 “발목 잡는 API”
  • React 생태계 전체에서 과사용된 대표적 문제 지점
    → 구조적으로 실수하기 쉬운 패턴

⬛ 2020: Custom hook — useFetch로 축약

  • 중복 로직(loading/error/data)을 훅으로 감춤
  • useEffect를 감싸 안전·일관적인 패턴 제공
    → DX 개선이지만 한계 존재

⬛ 2021: React Query(현 tanstack query)의 등장

  • 캐시·리트라이·포커스 리프레시·백그라운드 업데이트 등을 자동 처리
  • “실수 방지하는 API”
  • throwOnError로 에러 처리 자동화 → async 에러 문제 해결
    사실상 useEffect 기반 API의 종결자

⬛ 2023: Suspense for Data Fetching

  • “로딩 상태를 컴포넌트가 아닌 부모 Suspense가 담당”
  • 클라이언트에서도 Suspense Query로 패칭 정리
    → 로딩 코드를 각 컴포넌트에서 제거 가능

⬛ 2024: React Server Components(RSC)

  • 서버에서 async fetch를 바로 쓸 수 있는 모델
  • 무거운 라이브러리(dayjs 등)를 클라이언트로 보내지 않아도 됨
  • JSON→문자열만 보내므로 대형 응답/그래프 렌더에 유리
    → 성능·보안·DX 모두 개선

⬛ 2025: Sync Engine 시대 도래 (Convex/ElectricSQL 등)

  • 데이터 변경이 클라이언트에 즉시 반영(실시간)
  • 오프라인에서도 쓰기 가능 → 재접속 시 서버로 자동 동기화
  • 낙관적 UI/콜라보레이션 기능이 자동 제공
    → 2026~ 이후 본격 확산 예상

3. 에러 처리: 왜 대부분의 React 앱이 위험한가

문제

  • 대부분의 실무 React 프로젝트는 ErrorBoundary가 거의 없음
  • async 에러는 ErrorBoundary에 포착되지 않음
  • 클릭 핸들러 에러도 포착되지 않음
    → 결과: 사용자는 하얀 화면(White Screen of Death)

해결

1) 루트 ErrorBoundary는 필수

2) 페이지 단위 ErrorBoundary도 필요

  • 네비게이션/푸터는 정상 유지
  • 위젯별 개별 에러 격리 가능
    → “도메인 단위 장애 격리” 실현

3) throwOnError (React Query)

  • async 에러를 자동으로 동기 에러로 변환
  • ErrorBoundary로 자연스럽게 전달
    → 에러 핸들링 실수를 원천 봉쇄

4. 런타임 타입 검증: 왜 TypeScript만으론 부족한가 (What)

TypeScript는 빌드 타임 검증만 한다.
API가 잘못된 JSON을 보내면 런타임에서는 무용지물.

→ 해결책: Zod

Zod 사용 효과

  • API 응답이 기대 타입과 다르면 즉시 에러
  • 런타임에서 타입 검증
  • 의도치 않은 JSON 구조 변화를 초기 단계에서 발견
  • 실무에서 대규모 품질 개선

실무 사례

  • 오류를 무시하려던 클라이언트에게 Zod가 문제를 조기 발견
  • “엄격하게 잡은 스키마가 실제 DB와 불일치” → API/DB 정리가 가능해짐

프론트엔드에서 가장 undersold된 필수 기술


5. Suspense + RSC 조합의 핵심 가치 (How)

Suspense

  • 데이터 로딩을 상위에서 처리
  • 개별 컴포넌트 코드가 단순해짐

RSC

  • 서버에서 직접 async/await 가능
  • 무거운 라이브러리를 클라이언트에 보내지 않음
  • 대용량 데이터/이미지/차트 렌더 시 극적으로 유리

예: 서버에서 차트 렌더링

  • 3만 포인트를 클라이언트로 보내 JSON 파싱
    → 느림
  • 서버에서 이미지로 렌더해 문자열만 전송
    → 즉시 표시

RSC의 진짜 가치는 대규모 계산/무거운 의존성을 브라우저에서 제거하는 것


6. Sync Engine: React 개발 방식의 미래

Sync Engine 개념

  • 데이터를 local-first로 저장
  • 즉시 쓰기 가능
  • 서버와 자동 동기화
  • 오프라인 지원
  • 여러 클라이언트에서 실시간 반영

예시 시나리오

  • A가 차량을 “Sold”로 변경 → B의 화면에서 즉시 반영
  • A가 오프라인인 상태에서도 로컬 저장 → 돌아오면 자동 sync
  • 3G 환경에서도 UI는 즉각 반응 → 서버 반영은 비동기 처리

개발자 경험(DX)이 강력함

  • DB API를 TypeScript로 정의 → 자동으로 클라이언트 함수 생성
  • 낙관적 UI 자동
  • 서버/클라이언트 동기화 코드 제거
  • CRUD 로직 단 한 줄로 구성 가능

단점: 아직 생태계 조성 초기
예상: 2026년 실무 확산 시작

추천 엔진:

  • Convex (안정적)
  • ElectricSQL
  • Jazz
  • Zero
  • TanStack DB(기존 REST/GraphQL을 그대로 사용 가능)

7. React 상태 관리의 8가지 카테고리

저자가 10년간 정리한 실전 분류 기준:

  1. URL
  2. Web Storage
  3. Local State (useState)
  4. Lifted State
  5. Derived State
  6. Refs
  7. Context
  8. Remote State (API)

핵심 원칙

  • 상태는 가능한 가까운 곳에 둔다
  • URL은 거의 항상 과소평가된다
  • Derived State는 상태로 저장하지 말고 “계산”한다
  • Context는 “변동 적은 값만” 넣는다
  • Remote State는 React Query·SWR·Router Loader 등에서 처리
  • 복잡도 기준으로 third-party state 선택(Zustand 선호)

8. 상태 관리 선택 기준 (Flowchart 요약)

단계 1: URL로 표현 가능한가?

→ URL 상태로 관리

단계 2: 서버에서 온 데이터인가?

  • 여러 페이지에서 공유 → React Query 등 Remote State
  • 단일 페이지 → Router Loader 또는 Suspense

단계 3: 공유가 필요한가?

  • 아니면 local state
  • 넓게 공유해야 한다면 Zustand/Context

단계 4: Form인가?

  • useState/useReducer
  • 복잡하면 React Hook Form/TanStack Form

9. React 19의 의미

React 팀이 그동안 개발자들이 만들어 쓰던 패턴을 공식 기능으로 편입한 업데이트
→ “카우패스 포장(paving the cowpaths)”

React 19가 제공하는 것:

  • Action state
  • Form actions
  • Server Actions
  • useOptimistic
  • useFormStatus
  • 기타 총 19개의 기능적 보완

→ 복잡한 패턴을 React가 직접 안내하는 형태로 발전


10. 실전 팁(저자 10년 경험 기반)

  • 컴포넌트를 작게 유지
  • 상태는 작은 단위에서 시작 → 필요 시 리프트
  • Context 남용 금지 (Zustand 추천)
  • Derived State 적극 활용
  • Form 라이브러리 대부분 필요 없음
  • 상태/JSX 반복되면 hook/component로 추출
  • Zod 도입으로 런타임 안정성 확보
  • Remote State 해결(React Query/Suspense/RSC/Sync Engine) 시 React 난이도 대폭 감소

참고 - Lessons from 10 years of React

profile
okorion's Tech Study Blog.

0개의 댓글