概要
2024年12月5日(木)に React 19 が発表されたので、内容をまとめます。
主な新機能
アクション (Action)
データの書き換えと状態更新を簡素化する新機能です。非同期関数をトランジション内で使用することで、送信中状態、エラー処理、楽観的更新を自動的に管理します。
useTransition
トランジション内で非同期関数を使用することで、送信中状態、エラー、フォーム、楽観的更新を自動的に処理するためのサポートが追加されました。
// Using pending state from Actions
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>
);
}
新しいフック
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,
);
アクションをラップしたものが返されます。ラップされたアクションが呼び出されると、useActionState はアクションの最終結果を data
として、アクションの進行中状態を pending
として返します。
useActionStateは以前のリリースではuseFormStateと呼ばれていましたが、
名前が変更され、useFormStateは非推奨になったようです。
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>
);
}
updateName
リクエストが進行中になると、optimisticName
を即座にレンダリングします。
更新が完了するかエラーが発生すると、自動的に currentName
の値に戻します。
useFormStatus (React DOM)
フォームの状態にアクセスするためのフックです。
import {useFormStatus} from 'react-dom';
function DesignButton() {
const {pending} = useFormStatus();
return <button type="submit" disabled={pending} />
}
useFormStatus
を使うことで、親フォーム自体がコンテキストプロバイダのように、親<form>
の状態を読み取れます。
フォーム関連の改善
form
要素の action属性に関数を直接渡すことが可能になり、フォーム送信時の処理がより柔軟になりました。<form>
、<input>
、<button>
の各要素において、props である action および formAction に関数を渡すことがサポートされるようになりました。これによりアクションを用いて自動的にフォームの送信が可能です。
新しいAPI use
レンダリング中にリソースを読み取るための新しいAPIであるuse
が導入されました。
use
でプロミスを読み取り、プロミスが解決resolve
するまで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>
)
}
ref が props に
関数コンポーネントにおいて ref に props としてアクセスできるようになりました。
function MyInput({placeholder, ref}) {
return <input placeholder={placeholder} ref={ref} />
}
//...
<MyInput ref={ref} />
新しい関数コンポーネントでは forwardRef
が不要になります。新しい props
である ref
を使用するようコンポーネントを自動的に更新する codemod が公開される予定です。将来のバージョンでは forwardRef
は非推奨となり、削除されます。
クラスに渡された ref はコンポーネントインスタンスを参照するため、props としては渡されません。
<Context>
がプロバイダに
React 19 では、 の代わりに をプロバイダとしてレンダーできるようになりました。
const ThemeContext = createContext('');
function App({children}) {
return (
<ThemeContext value="dark">
{children}
</ThemeContext>
);
}
新しいコンテクストプロバイダは のように使用できるため、既存のプロバイダを変換するための codemodが公開される予定です。将来のバージョンでは は非推奨になる予定です。
最後に
今回のバージョンアップでは便利な機能がいくつも追加されたと感じます。
今後の更なるアップデートにも注目していきたいです。
参考