React 19正式リリース!新機能と改善点を徹底解説

Reactの最新バージョンである「React 19」が2024年12月5日にリリースされた。 本記事では、React 19の新機能と改善点を詳しく解説していく。

目次

Actions

フォーム送信やデータ操作後の状態管理がより簡単に行えるようになった。

従来のコード
従来は、useStateで進行中の状態 (pending)を個別に管理する必要があった。

function UpdateName() {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, setIsPending] = useState(false);

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

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

React 19での改善例
useTransitionを利用することで、状態管理が自動化される。

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={(e) => setName(e.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>更新</button>
      {error && <p>{error}</p>}
    </div>
  );
}

useActionState

Actionsの利用をさらに簡単にするため、useActionStateフックが追加された。このフックにより、ペンディング状態やエラーハンドリングがより直感的に実装できるようになった。

const [error, submitAction, isPending] = useActionState(
  async (previousState, newName) => {
    const error = await updateName(newName);
    if (error) {
      // You can return any result of the action.
      // Here, we return only the error.
      return error;
    }

    // handle success
    return null;
  },
  null,
);

form

React 19では、<form>の新機能として、actionプロパティに関数を渡せるようになり、自動的にフォームを送信する「Actions」がサポートされた。

<form action={actionFunction}>

useFormStatus

<form>の情報をコンポーネントに渡すためにContextを使うことがあるが、これを簡単にするために新しいフックuseFormStatusが追加された。

useFormStatusを使うと、親の<form>の状態をContextプロバイダーのように取得できる。

import {useFormStatus} from 'react-dom';

function DesignButton() {
  const {pending} = useFormStatus();
  return <button type="submit" disabled={pending} />
}

useOptimistic

いいねボタンなどデータの変更時に、非同期リクエスト中でも最終状態を楽観的に表示するUIパターンが一般的であるが、React 19では、この処理を簡単にするために新しいフックuseOptimisticが追加された。

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>
  );
}

use

React 19では、新しいAPIとしてuseが導入された。useを使うと、レンダー中にPromiseを読み込むことができ、Promiseが解決するまでReactは自動的にSuspendされる。

import {use} from 'react';

function Comments({commentsPromise}) {
  // `use` will suspend until the promise resolves.
  const comments = use(commentsPromise);
  return comments.map(comment => <p key={comment.id}>{comment}</p>);
}

function Page({commentsPromise}) {
  // When `use` suspends in Comments,
  // this Suspense boundary will be shown.
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Comments commentsPromise={commentsPromise} />
    </Suspense>
  )
}

prerender・prerenderToNodeStream

React 19では、静的サイト生成向けにreact-dom/staticに新しいAPIprerenderprerenderToNodeStreamが追加された。

これらのAPIはrenderToStringを改善し、静的HTML生成時にデータのロードを待機する。Node.js StreamsやWeb Streamsなどのストリーミング環境で使用可能。

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 Server Components

サーバー側で事前にコンポーネントをレンダリングできるReact Server Componentsが安定版として提供された。

Server Actions

クライアントコンポーネントからサーバー上の非同期関数を呼び出す機能であるServer Actionsが安定版として提供された。

refのプロパティ化

React 19では、関数コンポーネントでrefを直接プロパティとして渡せるようになった。これにより、従来のforwardRefを使ったコードが不要になる。

function MyInput({ placeholder, ref }) {
  return <input placeholder={placeholder} ref={ref} />;
}

<MyInput ref={ref} />;

Contextがプロバイダーとして使用可能に

React 19では、<Context.Provider>の代わりに、直接<Context>をプロバイダーとしてレンダリングできるようになった。

const ThemeContext = createContext('');

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

refのクリーンアップ関数

Reactでは、refコールバックからクリーンアップ関数を返すことが可能になった。

<input
  ref={(ref) => {
    // ref が作成されたときの処理

    // NEW: 要素がDOMから削除された際に
    // ref をリセットするクリーンアップ関数を返す
    return () => {
      // ref のクリーンアップ処理
    };
  }}
/>

useDeferredValueの初期値 (initialValue) サポート

useDeferredValueinitialValueオプションが追加された。

function Search({deferredValue}) {
  // 初回レンダー時、valueは空文字列 ''。
  // その後、バックグラウンドで deferredValue を使った再レンダーがスケジュールされる。
  const value = useDeferredValue(deferredValue, '');
  
  return (
    <Results query={value} />
  );
}
  • 初期値 (initialValue) を指定可能。
  • コンポーネントの初回レンダーではinitialValueを返し、バックグラウンドでdeferredValueに基づく再レンダーをスケジュール。
  • ユーザー体験の改善やパフォーマンス最適化に役立つ。

メタデータのネイティブサポート

React 19では、<title><meta><link>などのドキュメントメタデータタグをコンポーネント内でネイティブに扱えるようになった。

Reactがこれらのタグを自動的に検出し、HTMLドキュメントの<head>セクションに移動(hoist)する。

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>
        Eee equals em-see-squared...
      </p>
    </article>
  );
}

まとめ

React 19のリリースにより、非同期処理の簡素化やサーバーサイドレンダリングの強化など、開発者にとって多くの利便性が向上した。 これらの新機能を活用することで、より高品質なユーザーインターフェースの構築が可能となる。 詳細やアップグレード手順については、公式のReact19アップグレードガイドをご参照ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次