Logo
Search|
Published on

[번역] 예제 코드와 함께 보는 새로운 리엑트 v19 심화편

Authors
  • avatar
    Name
    Easyoon
    Twitter

What's New in React v19?

원문

eact v19가 앱 개발을 혁신할 주요 업그레이드와 함께 출시되었습니다. 이번 릴리스에는 효율성을 개선하고 코드를 단순화하며 전반적인 성능을 향상시키는 것을 목표로 하는 새로운 도구와 기능이 포함되어 있습니다. React v19 설계자들은 사용자 정의 요소 지원 및 향상된 비동기 데이터 처리와 같은 다양한 업데이트를 추가하여 앱 개발을 개선하는 것을 목표로 했습니다. 이 업데이트는 더 나은 개발 경험과 더 빠른 앱을 약속합니다. 복잡한 양식, 성능 및 서버 측 렌더링에 도움이 됩니다.

개발자에게 React 19의 변경 사항은 미래의 웹 앱을 위해 필수적입니다. 성능 최적화, 복잡한 양식 구축 및 사용자 정의 요소 통합을 통해 프로세스를 개선합니다.

이전 블로그인 React 19 베타 기능에서도 React 19의 흥미로운 베타 기능 중 일부를 다루었습니다. 여기에서 향상된 비동기 렌더링 및 개선된 상태 관리 도구와 같은 예정된 변경 사항을 자세히 살펴보았습니다. React 개발의 미래를 미리 엿보려면 확인해 보세요!

주요 기능 및 개선 사항

1. 액션(Actions): 비동기 데이터 변경을 더 쉽게 만들기

React 앱에서 흔한 작업은 데이터 변경을 관리하는 것입니다. 여기에는 양식 제출이나 사용자 정보 업데이트가 포함됩니다. 이전 버전에서는 로딩, 오류 및 성공에 대한 상태를 수동으로 관리해야 했습니다. React 19에서는 액션이 이 프로세스를 단순화합니다. 이제 액션은 비동기 데이터 변경을 원활하게 처리하여 상용구 코드의 필요성을 줄입니다.

예를 들어, 사용자 이름을 업데이트하기 위해 양식을 제출하는 경우를 생각해 봅시다. React 19의 비동기 전환은 보류 중인 상태, 오류 및 낙관적 업데이트를 처리합니다. UI는 백엔드 응답을 기다리는 동안 즉각적인 피드백을 제공할 수 있습니다. 또한 React Server Components는 서버에서 데이터를 가져올 수 있으며 React 앱에 비동기 데이터를 더 효과적으로 통합할 수 있도록 합니다.

function UpdateName({}) {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();

  const handleSubmit = () => {
    startTransition(async () => {
      const error = await updateName(name);
      if (error) {
        setError(error);
        return;
      }
      redirect("/path");
    });
  };

  return (
    <div>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>
        Update
      </button>
      {error && <p>{error}</p>}
    </div>
  );
}

React 19에서 액션은 보류 상태를 관리하고 오류를 처리합니다. 또한 낙관적 업데이트를 지원하는데, 이는 백엔드가 응답할 때까지 UI가 즉각적인 피드백을 표시할 수 있음을 의미합니다.

2. useActionState: 일반적인 액션 작업 단순화

React 19의 새로운 useActionState 훅은 비동기 작업을 더 쉽게 처리할 수 있도록 도와줍니다. 이 훅은 양식 제출과 같은 비동기 작업을 관리하는 데 유용합니다. 로딩 및 오류 상태를 수동으로 처리하는 수고를 덜어줍니다. React 19의 접근 방식은 일반적인 액션을 기반으로 워크플로우를 크게 단순화하여 개발을 더 효율적이고 오류 발생 가능성을 줄여줍니다.

예를 들어, 다음과 같이 사용할 수 있습니다.

const [error, submitAction, isPending] = useActionState(
  async (previousState, newName) => {
    const error = await updateName(newName);
    if (error) {
      return error;
    }
    return null;
  },
  null,
);

이제 로딩 또는 오류 상태를 추적할 필요가 없습니다. useActionState가 이를 간소화해 줍니다.

3. React DOM: 향상된 <form> 처리

React 19에서 폼 처리는 액션을 <form>, <input>, 그리고 <button> 요소에 직접 통합하여 크게 향상되었습니다. 이제 React 19는 폼 제출을 액션 함수에 자동으로 연결하여 폼 재설정을 포함한 전체 프로세스를 관리합니다. 이 새로운 접근 방식은 클라이언트 컴포넌트와 React Server Components 간의 더 원활한 상호 작용을 가능하게 합니다. 데이터 전송이 서버와 클라이언트 사이에서 중단 없이 이루어지기 때문에 경험의 속도와 효율성을 극대화합니다.

function ChangeName({ name, setName }) {
  const [error, submitAction, isPending] = useActionState(
    async (previousState, formData) => {
      const error = await updateName(formData.get("name"));
      if (error) {
        return error;
      }
      redirect("/path");
      return null;
    },
    null,
  );

  return (
    <form action={submitAction}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </form>
  );
}

4. Optimistic을 사용한 낙관적 UI 업데이트

많은 앱에서 백엔드 처리가 완료되기 전이라도 사용자가 데이터를 제출한 직후 업데이트를 표시하는 것이 중요합니다. React 19는 이 시나리오를 처리하기 위해 optimistic 훅을 도입했습니다. 이를 통해 "낙관적" UI 업데이트를 표시할 수 있습니다. 시스템은 요청이 완료되면 실제 데이터로 이를 대체합니다. useOptimistic을 사용하면 요청이 진행되는 동안 사용자에게 새 이름을 즉시 표시할 수 있습니다. 문제가 발생하면 React는 수동 개입 없이 원래 값으로 되돌립니다. 이 동작은 컴포넌트 트리에 통합됩니다. 이를 통해 클라이언트 컴포넌트와 React Server Components 간의 더 원활한 상호 작용이 가능하며 백엔드가 요청을 처리하는 동안 UI를 업데이트합니다.

다음은 이를 사용하는 방법의 예입니다.

function ChangeName({ currentName, onUpdateName }) {
  const [optimisticName, setOptimisticName] = useOptimistic(currentName);

  const submitAction = async formData => {
    const newName = formData.get("name");
    setOptimisticName(newName);
    const updatedName = await updateName(newName);
    onUpdateName(updatedName);
  };

  return (
    <form action={submitAction}>
      <p>Your name is: {optimisticName}</p>
      <p>
        <label>Change Name:</label>
        <input
          type="text"
          name="name"
          disabled={currentName !== optimisticName}
        />
      </p>
    </form>
  );
}

5. 더 간단한 리소스 관리를 위한 use API 사용

React 19의 또 다른 주요 추가 기능은 비동기 리소스 작업을 단순화하는 새로운 useAPI입니다. 이제 렌더링에서 Promise를 직접 읽을 수 있으며 React는 Promise가 해결될 때까지 컴포넌트를 자동으로 일시 중단합니다. 이를 통해 비동기 데이터 가져오기 작업을 훨씬 쉽게 수행할 수 있습니다.

React를 사용하면 비동기 프로세스를 더 효과적으로 관리할 수 있습니다. 이를 통해 컴포넌트에서 데이터 가져오기를 더 잘 제어할 수 있습니다. 이 기능은 서버 측에서 데이터를 가져오는 React Server Components에서 잘 작동합니다. 로딩 중에도 UI는 응답성이 유지되고 일관성을 유지할 수 있습니다.

import { use } from 'react';

function Comments({commentsPromise}) {
  const comments = use(commentsPromise);
  return comments.map(comment => <p key={comment.id}>{comment}</p>);
}

6. 새로운 React DOM 정적 API

React 19는 더 나은 정적 사이트 생성을 위해 react-dom/static에 두 개의 새로운 API를 추가했습니다. 새로운 prerender 및 prerenderToNodeStream API는 정적 HTML 생성 중에 데이터 처리를 개선합니다. 특히 스트리밍 환경에서 유용합니다. 이는 서버 측 렌더링을 향상시키고 React로 정적 페이지를 생성하는 것을 더 쉽게 만듭니다.

이러한 API는 React가 정적 콘텐츠를 생성하는 능력을 향상시킵니다. 최신 웹 앱에서 서버 측 렌더링 성능을 향상시킵니다. 개발자는 React Server Components를 사용하여 매우 효율적으로 정적 콘텐츠를 생성할 수 있습니다. 또한 클라이언트 컴포넌트를 사용하여 동적 상호 작용을 구현할 수 있습니다.

import { prerender } from 'react-dom/static';

async function handler(request) {
  const { prelude } = await prerender(<App />, {
    bootstrapScripts: ['/main.js']
  });
  return new Response(prelude, {
    headers: { 'content-type': 'text/html' },
  });
}

서버 컴포넌트: React 앱의 미래

1. 서버 컴포넌트

React 19의 가장 큰 새로운 기능 중 하나는 서버 컴포넌트입니다. 이를 통해 앱의 특정 부분을 서버에서 완전히 렌더링하고 HTML만 클라이언트로 보낼 수 있습니다. 이는 더 빠른 페이지 로드, 더 나은 SEO, 그리고 더 가벼운 클라이언트 측 앱을 의미합니다.

서버 클라이언트 컴포넌트는 외부 JavaScript를 필요로 하지 않아 앱을 더 가볍고 효율적으로 만듭니다. 속도를 더욱 높이기 위해 클라이언트 대신 서버에서 직접 데이터를 가져올 수 있습니다.

예시:

'use server';

function ServerComponent() {
  const data = fetchDataFromDatabase();  // Data fetched on the server
  return <div>{data}</div>;
}

이러한 서버 측 렌더링으로의 전환을 통해 부담이 큰 작업을 서버로 오프로드하고 성능과 보안을 모두 개선할 수 있습니다.

2. 서버 액션

React 19는 또한 비동기 함수를 서버로 오프로드할 수 있도록 하는 서버 액션을 도입했습니다. 여기에는 데이터 가져오기, API 요청, 또는 기타 리소스 집약적인 작업과 같은 작업이 포함될 수 있습니다. 서버 액션을 사용하면 클라이언트 측 코드를 가볍게 유지하고 서버에서 무거운 작업을 처리하도록 할 수 있습니다.

예시:

'use server';

async function fetchData() {
  const response = await fetch('https://api.example.com/data');
  return await response.json();
}

이는 클라이언트의 작업량을 줄이고 전반적으로 더 빠르고 안전한 애플리케이션을 의미합니다.

3. 하이드레이션 오류 수정: React 앱의 더 명확한 디버깅

React 19는 하이드레이션 오류 디버깅을 더 쉽게 만듭니다. React가 서버 렌더링된 HTML을 클라이언트와 동기화할 때 불일치가 발생할 수 있습니다. 과거에는 React가 여러 개의 혼란스러운 오류 메시지를 기록하여 문제를 추적하기 어려웠습니다. 이제 React 19는 어디가 잘못되었는지 정확하게 강조 표시하는 차이와 함께 단일하고 명확한 오류 메시지를 표시하여 디버깅 프로세스를 가속화합니다.

4. React 19: <Context>를 Provider로 사용

React 19에서는 기존의 <Context.Provider> 대신 <Context>를 직접 Provider로 사용할 수 있습니다. 이렇게 하면 코드가 더 깔끔하고 직관적으로 됩니다.

예시:

const ThemeContext = createContext('');

function App({children}) {
  return (
    <ThemeContext value="dark">
      {children}
    </ThemeContext>
  );  
}

이러한 변경은 불필요한 코드를 줄이고 React가 <Context.Provider>를 더 이상 사용하지 않을 계획이므로 향후 업데이트를 위한 길을 열어줍니다. 기존 코드를 마이그레이션하는 데 도움이 되는 코드 모드도 제공될 예정입니다.

5. Refs의 정리 함수: 리소스 자동 관리

React 19는 refs에 정리 함수를 제공하여 타이머나 이벤트 리스너와 같은 부작용을 자동으로 관리하는 데 도움을 줍니다. 컴포넌트가 마운트 해제될 때 React는 refs를 정리합니다. 이는 메모리 누수를 방지하고 성능을 향상시키는 데 도움이 됩니다.

예시:

function MyComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    const current = myRef.current;
    current.addEventListener('click', handleClick);

    return () => {
      current.removeEventListener('click', handleClick); // Cleanup on unmount
    };
  }, []);

  return <button ref={myRef}>Click me</button>;
}

이를 통해 리소스 관리가 훨씬 쉬워지고 컴포넌트가 제거될 때 모든 것을 적절하게 정리할 수 있습니다.

6. UseDeferredValue 초기 값: 더 부드럽고 빠른 UI 업데이트

React 19는 UI를 차단하지 않고 비용이 많이 드는 업데이트를 관리하는 데 도움이 되는 useDeferredValue 훅에 초기 값을 설정하는 기능을 추가했습니다. 이는 대형 검색 창에 입력하는 것과 같이 빈번하거나 과도한 업데이트가 있는 경우에도 앱이 더 부드럽고 반응성이 좋아짐을 의미합니다.

예시:

function SearchComponent({ query }) {
  const deferredQuery = useDeferredValue(query, { initialValue: '' });

  return <div>Search query: {deferredQuery}</div>;
}

덜 중요한 업데이트를 지연시킴으로써 React는 UI가 빠르고 반응적으로 느껴지도록 유지합니다.

React 19의 문서 메타데이터 지원

이전 버전의 React에서는 제목, 작성자, 키워드와 같은 문서 메타데이터를 관리하려면 타사 라이브러리를 사용하거나 부작용에서 수동으로 처리해야 했습니다. React 19에서는 메타데이터 태그(<title>, <meta>, 그리고 <link>)를 컴포넌트 내부에 직접 배치할 수 있도록 하여 이를 더 쉽게 만듭니다. React는 자동으로 HTML의 <head> 섹션으로 옮깁니다.

예를 들어, 블로그 게시물 컴포넌트를 렌더링하는 경우:

function BlogPost({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <title>{post.title}</title>
      <meta name="author" content="Josh" />
      <link rel="author" href="https://twitter.com/joshcstory/" />
      <meta name="keywords" content={post.keywords} />
      <p>{post.content}</p>
    </article>
  );
}

이를 통해 메타데이터가 앱 전체에서 올바르게 처리되도록 하여 클라이언트 전용 앱, 스트리밍 SSR 및 서버 컴포넌트에서 작동하도록 보장할 수 있습니다. 더 복잡한 시나리오의 경우 추가 사용자 정의를 위해 React Helmet과 같은 라이브러리를 계속 사용할 수 있습니다.

더 스마트한 스타일시트 관리

React 19는 스타일시트 처리를 개선했습니다. 이제 스타일시트의 로드 순서와 중요도를 설정할 수 있습니다. 그러면 React는 이를 올바른 순서로 로드합니다. 이를 통해 컴포넌트 내에서 CSS 종속성을 더 쉽게 관리할 수 있습니다.

예를 들어:

function ComponentOne() {
  return (
    <Suspense fallback="loading...">
      <link rel="stylesheet" href="foo" precedence="default" />
      <link rel="stylesheet" href="bar" precedence="high" />
      <article className="foo-class bar-class">{/* content */}</article>
    </Suspense>
  );
}

React는 스타일이 올바르게 적용되도록 하여 레이아웃이 깨지는 것을 방지합니다. 또한 컴포넌트를 재사용하는 경우 React는 동일한 스타일시트를 여러 번 로드하지 않아 효율성을 유지합니다.

더 간단해진 비동기 스크립트

앱이 분석 또는 라이브러리와 같은 외부 스크립트에 의존하는 경우 React 19는 중복에 대한 걱정 없이 비동기적으로 로드하는 것을 더 쉽게 만듭니다. 스크립트를 여러 번 렌더링하더라도 React는 스크립트가 한 번만 로드되도록 합니다.

예를 들어:

function MyComponent() {
  return (
    <div>
      <script async={true} src="..."></script>
      Hello World
    </div>
  );
}

이는 서버와 브라우저 모두에서 작동하며 스크립트가 필요할 때만 로드되고 절대 중복되지 않도록 합니다.

프리로딩을 통한 성능 최적화

React 19는 글꼴이나 스크립트와 같이 브라우저가 조기에 로드해야 할 수 있는 리소스에 대해 브라우저에 알리는 새로운 방법을 도입했습니다. 이를 통해 앱 로드 속도를 높이고 중요한 리소스에 대한 대기 시간을 줄여 사용자 경험을 개선할 수 있습니다.

예를 들어:

import { preload, preinit } from 'react-dom';

function MyComponent() {
  preload('https://example.com/style.css', { as: 'style' });
  preinit('https://example.com/script.js', { as: 'script' });
}

이러한 프리로딩은 필요한 리소스가 전체 페이지가 먼저 로드될 때까지 기다리지 않고 사용자가 필요로 하는 즉시 사용할 수 있도록 보장합니다.

써드파티 스크립트 처리

React 19는 하이드레이션(서버에서 로드된 후 클라이언트에서 앱을 렌더링)을 개선했습니다. 이는 특히 써드파티 스크립트와 브라우저 확장을 사용하는 개발자에게 유용합니다. 과거에는 외부 스크립트가 예기치 않은 방식으로 페이지를 변경할 수 있었습니다. 이로 인해 React의 하이드레이션 과정에서 오류가 발생할 수 있었습니다. 새로운 업데이트는 React가 타사 스크립트의 인식되지 않은 태그를 무시하도록 합니다. 이는 하이드레이션 오류를 방지하고 앱을 안정화합니다. 즉, React 앱이 외부 스크립트 및 브라우저 확장과 함께 작동할 수 있음을 의미합니다. 이는 문제를 줄이고 성능을 향상시킵니다.

향상된 오류 보고

React 19는 오류 처리를 훨씬 간단하게 만들었습니다. 이전 버전에서는 오류가 여러 번 기록되는 경우가 많아 디버깅이 더 혼란스러울 수 있었습니다. 이제 React는 오류를 한 번만 기록하며 모든 세부 정보를 포함하여 문제를 추적하고 수정하기가 더 쉽습니다. 또한 오류 처리를 더 잘 제어할 수 있습니다. 오류를 포착하거나 포착되지 않은 상태로 둘 수 있습니다.

메타데이터 및 성능 관리

React 19는 앱의 메타데이터 태그를 관리하는 보다 간소화된 접근 방식을 도입했습니다. SEO 또는 소셜 미디어 미리보기를 위한 메타 태그를 처리하든 React는 웹 개발의 중요한 측면을 훨씬 쉽게 처리할 수 있도록 합니다.

이 업데이트는 SSR 개선과 함께 앱 로드 속도를 높이는 데 도움이 됩니다. 또한 서버 렌더링된 HTML과 클라이언트 측 상호 작용 간의 일관성을 향상시킵니다. React 19를 사용하면 앱 전체에서 메타데이터를 관리하는 것이 더 간단하고 효율적이 됩니다.

주요 변경 사항

  • 서버 측 렌더링(SSR): React는 이제 서버에서 클라이언트로 데이터를 전달하는 것을 더 쉽게 만듭니다. 속성은 문자열이나 숫자와 같은 단순 값을 전달하는 반면 개발자는 객체나 함수와 같은 더 복잡한 데이터를 생략합니다. 이를 통해 React Server Components가 더욱 효율적이 되고 서버에서 렌더링할 때 추가 처리가 필요하지 않습니다.

  • 클라이언트 측 렌더링(CSR): 사용자 정의 요소의 경우 React는 이제 요소의 속성에 해당하는 속성을 직접 설정하고 다른 데이터를 속성으로 전달합니다. 이 업데이트를 통해 React와 함께 웹 컴포넌트를 더 쉽게 사용할 수 있으며 컴포넌트 트리를 관리하는 방식을 개선하여 더 모듈화되고 유지 관리하기 쉬운 코드를 만들 수 있습니다.

React 19는 개발을 더 빠르고 원활하게 만듭니다. 더 안정적인 앱을 구축하는 데 도움이 됩니다. 타사 스크립트 처리, 오류 보고 및 서버 측 렌더링을 개선합니다. 또한 메타데이터 및 데이터 가져오기 관리를 단순화합니다. 개발을 간소화합니다. 따라서 번거로움 없이 훌륭한 사용자 경험을 만드는 데 집중할 수 있습니다.

React 19가 성능을 향상시키는 방법

React 19는 애플리케이션을 더 빠르고 효율적으로 만들기 위한 여러 가지 성능 개선 사항도 도입했습니다.

  • 하이드레이션 최적화: React는 이제 하이드레이션 오류를 보다 효과적으로 처리하여 서버 렌더링된 콘텐츠와 클라이언트 측 JavaScript 간의 더 나은 동기화를 보장합니다.

  • 정적 리소스 프리로딩: React는 글꼴, 이미지 및 기타 자산과 같은 리소스가 미리 로드되는 방식을 최적화하여 로드 시간을 줄이고 특히 데이터가 많은 앱에서 성능을 향상시킵니다.

  • 오류 보고 및 디버깅: 업데이트된 오류 보고 시스템은 개발자가 렌더링 또는 상태 관리 문제를 신속하게 진단하는 데 도움이 되는 자세한 메시지를 제공하여 디버깅을 더 빠르게 만들고 버그를 줄입니다.

개발자에게 이것은 무엇을 의미할까요?

React 19는 개발자의 작업을 용이하게 하는 새로운 도구를 제공합니다. 반복적인 코드를 줄이고 앱 성능과 사용자 경험을 개선합니다. 다음과 같습니다.

  • 반복적인 코드 감소: useActionStateuseFormStatus와 같은 새로운 후크는 상용구 코드를 줄일 수 있습니다. 그러면 앱의 로직에 더 집중할 수 있습니다. 이는 코드를 깔끔하고 간결하며 유지 관리하기 쉽게 만드는 데 도움이 됩니다.

  • 향상된 UX: React 19를 사용하면 낙관적 UI 업데이트와 양식 제출을 더 쉽게 사용할 수 있습니다. 사용자는 앱을 사용한 후 즉각적인 피드백을 볼 수 있습니다. 이는 백엔드가 처리를 완료하기 전에 발생합니다. 이러한 반응성은 앱이 더욱 상호 작용적이고 빠르게 느껴지도록 하는 데 도움이 됩니다.

  • 더 빠른 성능: React 19에는 여러 가지 성능 향상이 있습니다. 여기에는 서버 측 렌더링(SSR) 최적화, 더 나은 로딩 및 더 스마트한 오류 처리가 포함됩니다. 앱이 더 빠른 속도로 로드되고 향상된 효율성으로 작동합니다. 또한 클라이언트와 서버 상태가 일치하지 않는 하이드레이션 오류를 방지합니다. 이는 사용자에게 더 나은 경험을 제공합니다.

React 19는 앱의 메타데이터와 스타일을 관리하는 방식을 개선합니다. 문서 메타데이터 태그 추가 및 적절한 정리 함수 보장과 같은 작업을 간소화합니다.

또한 사용자 정의 요소가 이제 더 잘 지원되므로 웹 컴포넌트 작업을 더 쉽게 수행할 수 있습니다. 이를 통해 컴포넌트를 설계하고 앱에 통합하는 방법에 더 큰 유연성을 얻을 수 있습니다.

결론

전반적으로 React 19에는 앱 개발을 한 단계 더 발전시키는 기능이 있습니다. 더 빠르고 효율적이며 더욱 즐겁습니다. 복잡한 양식을 구축하든, 사용자 정의 웹 컴포넌트 작업을 하든, 앱의 서버 측 렌더링을 개선하든 React 19가 지원합니다. 시간을 절약하고 복잡성을 줄이며 사용자에게 빠르고 원활한 경험을 제공하는 것을 목표로 합니다.

항상 그렇듯이 "export default function"을 사용하면 모듈화되고 재사용 가능한 컴포넌트를 만들 수 있습니다. 코드베이스를 체계적이고 관리하기 쉽게 유지합니다. 이러한 새로운 업데이트는 개발을 간소화하는 것을 목표로 합니다. 또한 사용자가 빠르고 원활한 경험을 할 수 있도록 보장합니다.