📘

React 19 まとめ(日本語)

2024/12/06に公開

概要

2024年12月6日(金)に React 19 が発表されたので、内容をまとめます

アクションの導入

React 18 から導入された useTransition hooks の返り値である startTransition のコールバック関数の中で async await を使用した非同期関数が使用できるようになリました

React v18 では、使用することができませんでした。(詳細はこちら
※ 以下スクリーンショット、公式ドキュメントから抜粋

// React v18
// ❌ Setting state *after* startTransition call
startTransition(async () => {
  await someAsyncFunction();
  setPage('/about');
});

// React v19
// ✅ Setting state *after* startTransition call
startTransition(async () => {
  await someAsyncFunction();
  setPage('/about');
});

新しいフックの追加

アクションの仕組みを土台として
react と react-dom に新たなフックが追加されました。

  • react
    • useOptimistic: 楽観的なUI更新を簡単に実装するためのフック
    • useActionState: アクションの結果に基づいて状態を更新するためのフック
  • react-dom
    • useFormStatus: フォームの送信状態(送信中、エラーなど)を追跡するためのフック

フォーム要素の強化

<form>要素の action属性 に関数を直接渡すことが可能になり、フォーム送信時の処理がより柔軟になりました。<form>、<input>、<button> の各要素において、props である action および formAction に関数を渡すことがサポートされるようになりました。これによりアクションを用いて自動的にフォームの送信が可能です。

<form action={actionFunction}>

<form> アクションが成功すると、React は非制御コンポーネントの場合にフォームを自動的にリセットします。手動で <form> をリセットする必要がある場合は、新しい React DOM の API である requestFormReset を呼び出すことができます。

新しいAPI use の導入

React 19 では、レンダー中にリソースを読み取るための新しい API である use を導入しています。たとえば、use でプロミスを読み取ることができます。プロミスが解決 (resolve) するまで React はサスペンドします。use API は、フックと同様にレンダー中にのみ呼び出すことができます。しかしフックとは異なり、use は条件分岐の中でも呼び出すことが可能です。将来的には、use を使用してレンダー中にリソースを使用する方法をさらに拡充する予定です。

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

ref が props として渡せるように

React 19 から、関数コンポーネントにおいて ref に props としてアクセスできるようになりました。なので、新しいコンポーネントでは forwardRef が不要になります。将来のバージョンでは forwardRef は非推奨となり削除される予定です。

React 18 まで

import React, { forwardRef } from 'react';

type Props = {
  placeholder?: string
}

const MyInput = forwardRef<HTMLInputElement, Props>((props, ref) => {
  return <input placeholder={props.placeholder} ref={ref} />;
});

//...
<MyInput ref={ref} />

React 19

import React, { forwardRef } from 'react';

type Props = {
  placeholder?: string
  ref: RefObject<HTMLInputElement>
}

const MyInput = (props: Props) => {
  return <input placeholder={props.placeholder} ref={props.ref} />;
});

//...
<MyInput ref={ref} />

Context が Provider に

<Context.Provider> の代わりに <Context> をプロバイダとしてレンダーできるようになりました。

React 18 まで

const ThemeContext = createContext('');

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

React 19

const ThemeContext = createContext('');

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

最後に

これで Next.js 15 も Stable になったし、React の 19 も Stable になりましたね

参考文献

https://ja.react.dev/blog/2024/04/25/react-19
https://react.dev/blog/2024/12/05/react-19

Discussion