React 19.2 업데이트 알아보기

이상범·2025년 10월 10일
0

2025년 10월 1일 - React 팀
React 19.2가 npm에서 사용 가능합니다!

React


📋 목차


들어가며

이번 릴리스는 12월의 React 19와 6월의 React 19.1에 이어 지난 1년간 세 번째 릴리스입니다.
React 19.2의 새로운 기능과 주목할 만한 변경사항이 어떤 게 있는지 알아보겠습니다!

🎯 주요 업데이트

카테고리기능
React Core<Activity />, useEffectEvent, cacheSignal, Performance Tracks
React DOMPartial Pre-rendering
개선사항SSR Suspense 일괄 처리, Node Web Streams 지원
도구eslint-plugin-react-hooks v6

새로운 React 기능

🎭 Activity 컴포넌트

<Activity>를 사용하면 앱을 제어하고 우선순위를 지정할 수 있는 "활동"으로 분할할 수 있습니다.
그리고, 컴포넌트를 언마운트하지 않고 숨기면서 state는 유지하고 effects만 정리할 수 있어, 기존 조건부 렌더링보다 유연한 제어가 가능합니다.

기본 사용법

// ❌ 이전 방식
{isVisible && <Page />}

// ✅ 새로운 방식
<Activity mode={isVisible ? 'visible' : 'hidden'}>
  <Page />
</Activity>

지원 모드

모드설명
visible자식을 표시하고, effect를 마운트하며, 업데이트를 정상적으로 처리
hidden자식을 숨기고, effect를 언마운트하며, 모든 업데이트를 연기

💡 주요 이점

  • 🚀 성능 최적화: 화면에 보이는 것의 성능에 영향 없이 숨겨진 부분을 미리 렌더링
  • 🔄 빠른 네비게이션: 백그라운드에서 데이터, CSS, 이미지 로드
  • 💾 상태 유지: 뒤로 탐색 시 입력 필드 같은 상태 보존

🎪 useEffectEvent 훅

useEffect에서 이벤트 핸들러를 분리하여 불필요한 재실행을 방지합니다.

문제 상황

// ❌ theme이 변경되면 채팅방이 다시 연결됨
function ChatRoom({ roomId, theme }) {
  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      showNotification('Connected!', theme);
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId, theme]); // theme 변경 시 재연결!
}

해결 방법

// ✅ useEffectEvent로 이벤트 분리
function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);
  });

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.on('connected', () => {
      onConnected();
    });
    connection.connect();
    return () => connection.disconnect();
  }, [roomId]); // ✅ theme은 의존성 배열에서 제외
}

⚠️ 사용 시 주의사항

언제 사용해야 할까요?

  • ✅ Effect에서 발생하는 개념적인 "이벤트"에 사용
  • ❌ 단순히 lint 오류를 무시하기 위해 사용 금지
  • 📌 eslint-plugin-react-hooks@6.1.1 이상 필요

🔄 cacheSignal API

React Server Components 전용

cache() 수명 주기를 추적하여 불필요한 작업을 정리할 수 있습니다.

import { cache, cacheSignal } from 'react';

const dedupedFetch = cache(fetch);

async function Component() {
  await dedupedFetch(url, { signal: cacheSignal() });
}

정리 시점

  • ✅ React가 렌더링을 성공적으로 완료
  • 🛑 렌더링이 중단됨
  • ❌ 렌더링이 실패함

📊 Performance Tracks

Chrome DevTools에 새로운 성능 프로필 트랙이 추가되었습니다!

1️⃣ Scheduler ⚛ 트랙

React가 다양한 우선순위로 작업을 처리하는 과정을 시각화합니다.

🟦 Blocking   ← 사용자 상호작용
🟩 Transition ← startTransition 업데이트

확인 가능한 정보:

  • 업데이트를 예약한 이벤트
  • 렌더링 발생 시점
  • 우선순위 대기 상황
  • Paint 대기 시간

2️⃣ Components ⚛ 트랙

컴포넌트 렌더링과 effect 실행을 추적합니다.

📌 Mount   ← 컴포넌트/effect 마운트
⏸️ Blocked ← React 외부 작업으로 양보

성능 문제 식별:

  • 렌더링 시점
  • Effect 실행 시점
  • 작업 완료 시간

새로운 React DOM 기능

🎨 Partial Pre-rendering

앱의 일부를 미리 렌더링하고 나중에 재개하는 강력한 기능입니다.

작동 방식

graph LR
    A[Static Parts] -->|CDN| B[Prelude Shell]
    B --> C[Dynamic Content]
    C --> D[Complete Page]

구현 예제

1단계: 사전 렌더링
const { prelude, postponed } = await prerender(<App />, {
  signal: controller.signal,
});

// postponed 상태 저장
await savePostponedState(postponed);

// prelude를 CDN으로 전송
2단계: SSR 재개
const postponed = await getPostponedState(request);
const resumeStream = await resume(<App />, postponed);

// 스트림을 클라이언트로 전송
3단계: SSG 재개
const postponedState = await getPostponedState(request);
const { prelude } = await resumeAndPrerender(<App />, postponedState);

// 완전한 HTML을 CDN으로 전송

📚 새로운 API

react-dom/server

  • resume - Web Streams용
  • resumeToPipeableStream - Node Streams용

react-dom/static

  • resumeAndPrerender - Web Streams용
  • resumeAndPrerenderToNodeStream - Node Streams용

주목할 만한 변경사항

🎯 SSR을 위한 Suspense 경계 일괄 처리

클라이언트와 서버의 렌더링 동작을 일치시키는 중요한 개선사항입니다.

Before vs After

이전 (19.1)

┌─────────────┐
│ Loading... │  ← 즉시 대체
├─────────────┤
│ Content A  │  ← 즉시 표시
├─────────────┤
│ Loading... │
└─────────────┘

현재 (19.2)

┌─────────────┐
│ Loading... │
├─────────────┤  ← 짧은 시간 일괄 처리
│ Content A  │
├─────────────┤
│ Content B  │  ← 함께 표시
└─────────────┘

💡 장점

  • 🎬 View Transitions 지원: 더 큰 단위로 애니메이션 실행
  • 성능 최적화: 연쇄 애니메이션 방지
  • 📊 Core Web Vitals: LCP 메트릭 자동 고려

참고: React는 페이지 로드 시간이 2.5초에 가까워지면 자동으로 일괄 처리를 중단하여 메트릭에 영향을 주지 않습니다.


🌊 SSR: Node용 Web Streams 지원

Node.js 환경에서도 Web Streams API를 사용할 수 있습니다!

새로 추가된 API

// Web Streams 사용 가능
✅ renderToReadableStream
✅ prerender
✅ resume
✅ resumeAndPrerender

⚠️ 중요한 권장사항

Node.js에서는 Node Streams를 권장합니다!

// 🚀 권장: Node Streams (더 빠름)
renderToPipeableStream
resumeToPipeableStream
prerenderToNodeStream
resumeAndPrerenderToNodeStream

// ⚡ Web Streams는 Node에서 느리고 압축 미지원

🔧 eslint-plugin-react-hooks v6

Flat Config가 기본값으로 설정되고, React Compiler 기반 규칙을 선택적으로 사용할 수 있습니다.

레거시 설정 사용하기

// package.json 또는 eslint.config.js
{
  // ❌ 이전
  extends: ['plugin:react-hooks/recommended']
  
  // ✅ 레거시 유지
  extends: ['plugin:react-hooks/recommended-legacy']
}

🆔 useId 접두사 업데이트

기본 접두사가 변경되었습니다!

버전접두사이유
19.0.0:r:CSS 선택자 회피
19.1.0«r»특수문자 사용
19.2.0_r_View Transitions & XML 1.0 호환

변경 로그

✨ 기타 주목할 만한 변경사항

  • react-dom: hoistable 스타일에 nonce 사용 허용 (#32461)
  • react-dom: React 소유 노드를 Container로 사용 시 경고 추가 (#32774)

🐛 주목할 만한 버그 수정

분류설명PR
Context문자열화 개선 "SomeContext"#33507
useDeferredValuepopstate 무한 루프 수정#32821
useDeferredValue초기 값 버그 수정#34376
Client Actions양식 제출 충돌 수정#33055
SuspenseDehydrated 경계 처리 개선#32900
Hot Reload스택 오버플로 방지#34145
Component Stacks다양한 개선#33629
React.uselazy 컴포넌트 내 버그 수정#33941
ARIA1.3 속성 경고 제거#34264
Suspense중첩 Suspense 버그 수정#33467
SSR렌더링 중단 후 멈춤 방지#34192

📚 참고 자료


🎉 마무리

React 19.2는 성능 최적화, 개발자 경험 개선, 그리고 서버 사이드 렌더링의 강화를 가져왔습니다. 특히 <Activity> 컴포넌트와 useEffectEvent 훅은 실무에서 바로 활용할 수 있는 강력한 기능입니다.

지금 바로 업데이트하고 새로운 기능을 경험해보세요! 🚀

npm install react@19.2 react-dom@19.2
profile
프론트엔드 입문 개발자입니다.

0개의 댓글