[React] React19에 관하여

김건휘·2024년 5월 28일
0

React

목록 보기
5/18
post-thumbnail

✔️들어가며

이번 시간에는 React19 즉, React 18 이후의 다음 버전으로 예상되는 React의 주요 업데이트의 예상되는 주요 특징 및 변화에 대해서 알아보는 시간을 가져보겠습니다. 현재 React 19에 대한 구체적인 정보는 공개되지 않았으므로, 일반적인 버전 업데이트에서 예상할 수 있는 변화를 바탕으로 작성해보겠습니다.

React 19는 React 라이브러리의 최신 주요 업데이트로, 성능 향상과 개발자 경험 개선을 목표로 하는 여러 새로운 기능과 개선 사항을 도입할 전망입니다.

✔️주요 변경점

React Compoiler

React 19 버전의 주요 변화 중 하나는 리액트 컴파일러이다.
리액트 컴파일러는 리액트 코드를 일반 자바스크립트 코드로 변환한다.
주요 이점으로 전반적인 앱 성능을 향상 시키는 것이지만 더 좋은 점은 개발자가 성능에 대해 많은 고민을 할 필요가 줄어들었다.
기존에는 불필요한 렌더링을 줄이기 위해 메모이제이션(Memoization)을 위한 useCallback, useMemo와 같은 것들을 사용해야 했다.
하지만, 메모이제이션 자체도 남발하면 오히려 성능이 저하되어서 개발하는 입장에서 이 기준을 명확히 잡는데 고민이 필요했다.
이런 문제를 리액트 컴파일러가 자동으로 리액트 코드를 최적화하여 이런 문제로 고민할 필요가 줄어들었다.
즉, 위에서 언큼한 메모이제이션을 위한 훅들을 사용하지 않아도 된다.

요약

자동 메모이제이션: React 컴파일러는 모든 훅과 컴포넌트를 자동으로 메모이제이션한다. 이는 기존의 useMemo와 useCallback을 수동으로 사용할 필요를 줄여주며, 코드의 가독성과 유지보수성을 높여준다.

성능 최적화: 컴파일러는 비용이 많이 드는 계산을 자동으로 최적화하여, 개발자가 직접 최적화 코드를 작성하지 않아도 된다. 이를 통해 초기 로드 시간과 상호작용 속도가 크게 개선되었다.

비즈니스 로직에 집중: 개발자는 성능 최적화에 대한 부담을 덜고 비즈니스 로직 작성에 집중할 수 있게 되었다. 컴파일러가 자동으로 최적화를 처리하므로, 더 깔끔하고 유지보수하기 쉬운 코드를 작성할 수 있다.

✔️신규 Hook에 대한 소개

use(Context)

import { use } from 'react';

function HorizontalRule({ show }) {
  if (show) {
    const theme = use(ThemeContext);
    return <hr className={theme} />;
  }
  return false;
}

작동 방식

HorizontalRule 컴포넌트는 show prop을 받아, show가 참이면 ThemeContext의 값을 읽어와 hr 요소를 해당 테마로 렌더링합니다.
show가 거짓이면 아무 것도 렌더링하지 않는다.

use 훅의 특징

use 훅은 React 19에서 도입된 새로운 훅으로, 조건부로 컨텍스트 값을 읽어올 수 있다.
기존의 useContext 훅은 조건부로 사용할 수 없지만, use 훅은 조건문 내에서 사용할 수 있다

즉, 조건문 안에서 호출할 수 있다는 점만 다르고 기존 useContext와 동일하다.
(그런데 왜 이름을 use를 쓰는건지 이해가 안감)

useFormState

import React from 'react';
import { useFormState } from 'react-dom';

async function increment(previousState, formData) {
  return previousState + 1;
}

function StatefulForm() {
  const [state, formAction] = useFormState(increment, 0);

  return (
    <form>
      {state}
      <button formAction={formAction}>증가</button>
    </form>
  );
}

작동 방식

StatefulForm 컴포넌트가 렌더링될 때, useFormState 훅을 통해 상태와 폼 액션 핸들러를 설정합니다.
초기 상태는 0이며, increment 함수는 상태를 1 증가시키는 역할을 합니다.
폼 내에서 현재 상태가 표시되며, "증가" 버튼을 클릭하면 formAction이 호출되어 상태가 업데이트됩니다.

useFormStatus

import React from 'react';
import { useFormState, useFormStatus } from 'react-dom';

async function registerUser(previousState, formData) {
  // 서버에 폼 데이터 제출을 시뮬레이션합니다.
  await new Promise(resolve => setTimeout(resolve, 1000));
  return '등록 성공';
}

function RegistrationForm() {
  const [status, formAction] = useFormState(registerUser, '');
  const { isPending } = useFormStatus();

  return (
    <form>
      <input type="text" name="username" placeholder="사용자 이름" required />
      <input type="password" name="password" placeholder="비밀번호" required />
      <button formAction={formAction}>회원가입</button>
      {isPending && <p>제출 중...</p>}
      {status && <p>{status}</p>}
    </form>
  );
}

export default RegistrationForm;

작동 방식

useFormState는 폼의 상태를 관리하고, useFormStatus는 폼이 제출 중인지 여부를 추적하여 사용자에게 피드백을 제공한다. 이로 인해 사용자는 폼 제출 중임을 알 수 있고, 폼 제출이 완료되면 결과 메시지를 받을 수 있다.

React 18에서 Form action 작성시 Warning이 나오게 되는데 React 19부터는 useFormState와 useFormStatus 훅을 활용하여 점점 form이 고도화되고 있는 것을 지래짐작 할 수 있다.

useOptimistic

import { useOptimistic, useState, useRef } from "react";
import { deliverMessage } from "./actions.js";

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get("message"));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) => [
      ...state,
      {
        text: newMessage,
        sending: true
      }
    ]
  );

  return (
    <>
      {optimisticMessages.map((message, index) => (
        <div key={index}>
          {message.text}
          {!!message.sending && <small> (Sending...)</small>}
        </div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" placeholder="Hello!" />
        <button type="submit">Send</button>
      </form>
    </>
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: "Hello there!", sending: false, key: 1 }
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get("message"));
    setMessages((messages) => [...messages, { text: sentMessage }]);
  }
  return <Thread messages={messages} sendMessage={sendMessage} />;
}

작동 방식

사용자가 폼에 메시지를 입력하고 “전송” 버튼을 누르면, useOptimistic Hook은 메시지가 실제로 서버로 전송되기 전에 “전송 중…” 라벨이 있는 목록에 메시지가 즉시 나타나도록 한다. 그런 다음 폼은 백그라운드에서 메시지를 실제로 전송하려고 시도한다. 서버가 메시지를 받았음을 확인하면, “전송 중…” 라벨이 제거된다.

주요 기능

  • React 서버 컴포넌트 (Server Components):
    서버 컴포넌트는 클라이언트 애플리케이션이나 SSR 서버와 분리된 환경에서 미리 컴포넌트를 렌더링할 수 있게 해준다. 이를 통해 클라이언트 측의 작업 부담을 줄이고 성능을 개선할 수 있다.

  • 서버 액션 (Server Actions):
    서버 액션을 통해 클라이언트 컴포넌트가 서버에서 실행되는 비동기 함수를 호출할 수 있다. 이 기능은 무거운 계산 작업을 서버로 오프로드하여 클라이언트 성능을 향상시킨다.

  • Ref를 Prop으로 사용:
    함수형 컴포넌트가 이제 ref를 prop으로 직접 사용할 수 있어, forwardRef를 사용할 필요 없이 코드를 간소화할 수 있다.

  • 문서 메타데이터 관리 개선:
    React 19는 title, meta, link 태그를 React 컴포넌트 내에서 직접 관리할 수 있는 내장 지원을 도입하여, 추가 라이브러리 없이도 SEO와 접근성을 개선할 수 있다.

  • 웹 컴포넌트 통합:
    이제 웹 컴포넌트를 React 애플리케이션에 더 쉽게 통합할 수 있어, 기존의 유용한 웹 컴포넌트를 React와 함께 사용할 수 있다.

  • 향상된 자산 로딩:
    React 19는 Suspense와 자산 로딩을 통합하여 이미지, 스타일시트, 폰트 등의 자원을 부드럽게 로드하여 레이아웃 변경과 깜박임을 줄인다.

  • Deprecated 및 제거된 API:
    ReactDOM.render와 ReactDOM.findDOMNode와 같은 여러 오래된 API가 제거되었다. 개발자는 createRoot와 DOM refs와 같은 대안을 사용해야 한다.

profile
공유할 때 행복을 느끼는 프론트엔드 개발자

9개의 댓글

comment-user-thumbnail
2024년 5월 29일

메모이제이션 공부 깊게 안했는데 사라진다니 좀 좋네요..ㅎ use는 진짜 왜 이름이 use일까요 저도 이해가안되네요.. 여러가지 훅들이 많이 생겨서 공부를 다 해봐야겠네요! 유용해 보이는 훅들이 많은거 같아요~ 이제 ref를 prop으로 사용할수 있네요!! ref 못넘기고 forwardRef 쓰는거 진짜 불편했는데 좀 편해지겠네요!! 좋은 아티클 잘 보고갑니다! 덕분에 react19 전반적으로 잘 훝을수 있었습니다

답글 달기
comment-user-thumbnail
2024년 5월 29일

React Compoiler에 대한 부분에서 기존에는 개발자가 성능 최적화를 위해 많은 노력을 기울여야 했지만, React 19에서는 컴파일러가 자동으로 코드를 최적화해주어 개발자의 부담을 줄여주는 점이 인상 깊었습니다!
useFormState와 useFormStatus 훅에 대한 소개도 유익했어요! 폼 상태 관리와 폼 제출 상태를 추적하는 기능은 웹 애플리케이션에서 매우 중요한 부분이며, 이 두 훅이 어떻게 동작하는지 자세히 알 수 있어서 좋았습니다! 특히 폼 제출 중인 상태를 사용자에게 피드백으로 제공할 수 있는 점이 유용해보여요!
건휘님 아티클 통해 리액트19를 쉽게 이해할 수 있었습니다! 좋은 아티클 감사해요!

답글 달기
comment-user-thumbnail
2024년 5월 29일

메모이제이션과 관련된 변경 사항들을 자세히 정리해주셔서 확실히 React 19의 변경점이 체감되었던 것 같습니다 ! 그리고 새롭게 추가된 훅들의 사용방법을 예시와 함께 자세히 설명해주셔서(특히 .gif) 아티클을 읽는데 많은 도움이 되었던 것 같습니다. 작동 방식들에 대해서도 잘 풀어서 설명해주셔서 더더욱 초반에 대부분의 변경사항을 감 잡는데 도움이 되었던 것 같아요! 양질의 글 감사합니다 ~ 고생하셨어요!

답글 달기
comment-user-thumbnail
2024년 5월 29일

초반부에 모든 변경점들에 대해서 요약해서 정리해주셔서 한눈에 쉽게 파악할 수 있었습니다! 리액트 컴파일러의 변화에 대해선 첨 알게 됐네요! 복잡한 비즈니스 로직 작성에 집중할 수 있게 컴파일러가 자동으로 최적화하는 것도 흥미롭게 읽었습니다. 또, 신규 훅들에 대해서 깔끔한 정리 넘 좋구요 소소한 의견이 귀엽네요ㅋㅋ 자주 쓰는 회원가입 상황의 코드로 새로운 훅들을 더 잘 이해할 수 있었습니다 !
좋은 아티클 작성하시느라 고생 넘 많으셨습니다~~~

답글 달기
comment-user-thumbnail
2024년 5월 29일

새로 생긴 함수들에 대한 설명 뿐만 아니라 전체적인 변경점도 같이 설명해주셔서 리액트 19에서 자동 메모이제이션이 된다는 걸 알게 되었어요!
건휘님이 use 훅 이름이 왜 use인지 궁금하다고 하신 부분이 공감가서 좀 찾아봤는데, 두 가지 이유가 있다고 하네요?
1) use는 promise 뿐만 아니라 context, store 등 다양한 타입이 될 수 있기 때문
2) use는 조건부로 쓰일 수 있는 훅이기 때문. 다양한 조건에 맞게 쓰일 수 있기 때문에 use 하나로 묶게 됨
두 이유 모두 비슷한 느낌으로 다양한 역할로 쓰일 수 있기 때문인 것 같네요. 참고하시면 좋을 것 같습니다! 유용한 아티클 감사해요~!

답글 달기
comment-user-thumbnail
2024년 5월 29일

Hook 관련 내용 뿐만 아니라 전반적으로 어떤 변경된 부분들이 있는지 설명해 주셔서 너무 좋았습니다! 그 중에서도 컴파일러의 변경 사항을 소개해 주시고 관련 내용을 요약까지 해 주셔서 눈에 술술 들어왔어요! 초보 입장에서는 신규 hook이 생겼다는 게 공부할 거리가 생긴 것 같아 걱정되지만.... 그만큼 react에서 성능을 향상시켰다는 점을 중요하게 봐야 할 것 같네요 🥺 예제도 한 번쯤 고민할 만한 상황을 들어주셔서 hook의 사용법을 더 잘 이해할 수 있게 된 것 같습니다! 깔끔한 아티클 감사해요 💫

답글 달기
comment-user-thumbnail
2024년 5월 29일

React 19의 새로운 기능들과 주요 변경점에 대한 아티클 잘 읽었습니다! 특히 React 컴파일러를 통한 자동 메모이제이션과 성능 최적화 기능이 매우 흥미롭네요. 기존에 메모이제이션을 신경 써야 했던 부분들이 자동으로 최적화된다는 점에서 개발자들의 많은 부담을 덜어줄 것 같습니다. 신규 훅들인 use, useFormState, useFormStatus, useOptimistic 등도 각기 다른 상황에서 유용하게 사용할 수 있을 것 같아 기대가 됩니다. 새로운 버전이 정식 출시되면 꼭 적용해보고 싶네요.
좋은 글 감사합니다 !

답글 달기
comment-user-thumbnail
2024년 5월 29일

React Compiler가 변경된다는 점은 알고 있었지만 그로인해 메모이제이션을 위한 훅이 필요없어졌다는 부분은 새롭게 알게됐습니다. 메모이제이션이 필요한 부분은 알아서 처리를 해주기 때문에 그렇다는 거겠죠? 실습한 코드와 함께 실행 결과물을 첨부해주셔서 이해에 큰 도움이 되었습니다. React19 변경사항에 대한 아티클이 많이 없어서 공식문서 읽느라 엄청 쩔쩔맸는데 건휘님은 잘 이해하고 글에 녹이신 것 같네요! 좋은 아티클 감사합니다 :)

답글 달기
comment-user-thumbnail
2024년 5월 29일

와 안그래도 리액트 스터디 진행하면서 useMemo, useCallback, React.memo 에 대한 개념이 이해하기 어렵고 코드에 도입을 하려해도 여기에 쓰는게 과연 메모이제이션에 도움이 되는지 오히려 역효과가 나지는 않을지 고민이 많았었는데 이런 고민을 덜어준다니 리액트 컴파일러 만세~

답글 달기

관련 채용 정보