React 19에서의 근본적인 변화 - React(React)가 스벨트(Svelte)에게 배운 것

** 목 차 **


안녕하세요?

현재 기준 React 최신버전인 18.2 버전은 2022년 6월에 출시되었는데요.

그 이후로 새로운 공개 릴리즈가 없었습니다.

그러면 React 팀은 뭘 하고 있었을까요?

다시 말해, React 19에서 어떤 근본적인 변화를 기대할 수 있을까요?

이 질문에 답하려면 여러 가지 질문을 생각해봐야 합니다.

  • 리액트의 “카나리” 브랜치란 무엇인가?
  • useMemo 훅은 왜 만들어졌는가?
  • 스벨트(Svelte)가 리액트에 어떻게 영감을 주었는가?
  • 왜 리액트를 “단순한 라이브러리”라고 부르는 것이 더 이상 맞지 않는가?
  • React 19가 여러분의 삶을 어떻게 더 쉽게 만들 것인가?

카나리 브랜치 기능

2021년으로 되돌아가 보겠습니다.

리액트는 클라이언트 사이드 자바스크립트 라이브러리로 시작했습니다.

하지만 NextJS와 Remix 같은 서버 사이드 프레임워크들이 리액트를 사용하여 서버에서 콘텐츠를 렌더링하기 위한 해결책을 만들어내고 있었습니다.

이는 리액트를 새로운 방향으로 이끌었습니다.

프레임워크가 해결책을 개발할 필요 없이, React 팀은 그 작업을 내부화하기로 했습니다.

React 팀은 라이브러리를 서버에서 “자연스럽게” 작동하도록 재구성했습니다.

클라이언트 사이드는 클라이언트/서버 통신의 동기적 측면을 통합해야 했습니다.

그 결과 우리는 async/await의 UI 버전인 Suspense 컴포넌트를 얻게 되었습니다.

동시에 React 팀은 프레임워크 개발을 위한 “카나리” 브랜치를 설정했습니다.

카나리 브랜치의 기능은 개발자에게 직접 노출되지 않습니다.

대신 프레임워크(NextJS와 Remix 같은)가 이 기능을 기반으로 프레임워크를 빌드합니다.

예를 들어, React 19는 다음과 같은 기능을 도입합니다:

  • 서버 액션(Server Actions), 서버 사이드에서 로직을 실행할 수 있게 함
  • use 훅, 리액트에서 Promise와 상호작용할 수 있게 함
  • use clientuse server 지시어, 클라이언트/서버 구분을 명확히 하기 위해 코드의 일부를 구분할 수 있게 함

React 19의 주요 변경 사항

React 19의 가장 큰 변화는 컴파일러의 도입입니다.

리액트는 브라우저에서만 실행되었고, 컴파일 단계가 없었습니다.

그러나 이제는 Astro와 Svelte 같은 다른 프레임워크들이 컴파일 단계를 추가하여 많은 작업을 자동으로 처리해줍니다.

React 19버전에서는 컴파일러가 모든 것을 자동으로 처리해주기 때문에 useMemo, useCallback, memo 같은 훅을 더 이상 사용할 필요가 없습니다.

이는 코드가 더 간단하고 읽기 쉬워지며, 성능도 향상됨을 의미합니다.

컴파일러는 우리가 직접 찾는 것보다 더 많은 메모이제이션이 필요한 부분을 찾아내기 때문에, 이 추가적인 컴파일 단계는 애플리케이션을 더 빠르고 작성하기 쉽게 만들어줄 것입니다.

이외에도 React 19버전에서는 아래와 같은 새로운 기능들도 도입됩니다:

Actions

Next.js에서 form에 onSubmit 대신 action을 전달하면, 이 action은 form 데이터를 처리합니다.

React 19버전에서는 이 기능이 안정화되고, 클라이언트나 서버 어디서든 작동하게 됩니다.

또한 useFormStatus와 useFormState 같은 훅도 추가되어 상태 관리와 로딩 처리가 더 쉬워집니다.

이 훅은 클릭한 즉시 사용자가 원하는 상태를 보여주고, 서버 응답에 따라 최종 상태를 업데이트합니다.

"use client" and "use server" 지시어

Next.js에서 파일 상단에 "use client"나 "use server"를 추가하여 코드가 서버에서 실행되는지, 클라이언트에서 실행되는지 결정할 수 있습니다.

React 19버전에서는 이 기능이 안정화되어 다른 프레임워크에서도 사용할 수 있게 됩니다.

메타 데이터

React 컴포넌트 내 어디서든 title, meta, link 태그를 추가할 수 있으며, 자동으로 올바른 위치로 이동됩니다.

이는 서버 렌더링과 React 서버 컴포넌트에서 유용하게 사용될 것입니다.

Suspense 기능이 향상되어 스타일 태그, 링크, 스크립트가 로드될 때까지 대기할 수 있습니다.

웹 컴포넌트 호환성

React 19버전에서는 웹 컴포넌트와의 호환성이 크게 개선되었습니다.

이제는 웹 컴포넌트를 React 프로젝트에서 더 쉽게 사용할 수 있게 되었습니다.

기타 변경 사항

  • forwardRef를 더 이상 사용할 필요가 없습니다. 이제 ref prop이 모든 컴포넌트에 자동으로 전달되기 때문입니다.
  • React.lazy를 거의 사용할 필요가 없게 됩니다.
  • 새로운 use 훅이 추가되어 비동기 작업을 쉽게 처리할 수 있습니다.

useMemo의 필요성 이해하기

리액트의 기반은 기본적으로 함수형 프로그래밍에 기반하고 있습니다.

React 컴포넌트는 함수입니다.

props와 state를 입력으로 받아 사용자 인터페이스를 생성합니다.

주어진 input은 항상 동일한 output을 생성합니다.

이를 가능한 한 깨끗하게 유지하기 위해, 우리는 state(상태)를 사용하여 props(프롭스)나 state(상태)로부터 직접 도출될 수 있는 것을 저장하지 않습니다.

예를 들어, 보안 해시와 같은 계산이 복잡한 것을 계산하려고 한다고 가정해 보겠습니다.

컴포넌트가 렌더링될 때마다 무거운 계산이 다시 실행됩니다.

그리고 그 비싼 계산은 애플리케이션의 성능에 영향을 미칩니다.

이를 최적화하기 위해 useMemo가 설계되었습니다.

useMemo는 계산이 복잡한 함수의 “메모이제이션”을 수행합니다.

함수가 순수하기 때문에 출력은 입력에만 의존합니다.

그래서 useMemo를 호출하면 입력과 출력 쌍을 저장합니다.

동일한 입력으로 다시 호출되면 이전에 저장된 출력을 반환합니다.

그러나 useMemo최적화일 뿐입니다.

애플리케이션의 비즈니스 로직에 아무런 가치를 더하지 않습니다.

여기서 React 19는 스벨트(Svelte)의 전략을 차용합니다.

리액트와 스벨트의 차이점

리액트는 런타임에 반응성을 관리하지만, 스벨트(Svelte) 컴파일 타임에 이를 수행합니다.

스벨트(Svelte) 코드를 분석하고, 반응성이 어디에 있는지 결정하며, 업데이트가 필요한 부분을 연결합니다.

React 19는 최적화를 위해 유사한 작업을 수행합니다.

코드를 분석하는 컴파일러를 포함하고, 메모이제이션을 자동으로 설정합니다.

useMemouseCallback 훅을 선택 사항으로 만듭니다.

이는 개발자가 최적화 요구 사항으로 핵심 비즈니스 로직에 집중할 수 있게 해 줍니다.

React 19의 이 움직임은 개발자 경험을 단순화시킬수 있습니다.

코드 최적화 책임을 맡으며, 리액트의 컴파일러는 리액트를 더 단순하게 만듭니다.

그러나 이는 리액트가 더 이상 “단순한 라이브러리”가 아님을 의미합니다.

React 19는 이러한 변화들을 통해 개발자들의 삶을 더욱 쉽게 만들고, 더욱 효율적인 애플리케이션을 작성할 수 있도록 도와줍니다.

지금까지 React 19 버전에서의 주요 변화들을 살펴보았는데요.

앞으로 React 19의 새로운 기능들이 새로 만들 프로젝트에 어떤 영향을 끼칠지 궁금해지네요.

그럼.