9月5日、Vercelの公式ブログで「What’s new in React 19 – Vercel」と題した記事が公開された。この記事では、React 19における重要な新機能や改善点について、詳細かつ実践的な内容が取り上げられている。これまでのReactのバージョンで導入されてきた実験的機能が、React 19で正式に安定化され、多くの開発者にとってさらなるパフォーマンスの向上と開発体験の向上が期待されている。
ここでは、同記事からポイントを絞って内容をご紹介する。
サーバーコンポーネント (Server Components)
サーバーコンポーネントは、Reactの10年の歴史の中でも最も大きな変化の1つであり、React 19の新機能の基盤となるものである。この機能により、以下の点が大幅に改善される。
- 初期ページロード時間の短縮
- サーバーコンポーネントを使用すると、クライアントに送信されるJavaScriptの量が減少し、結果として初期表示が速くなる。さらに、データクエリがページがクライアントに送信される前にサーバー側で開始されるため、最初のレンダリングに必要な時間も短縮される。
- コードのポータビリティ
- サーバーコンポーネントにより、開発者はサーバーとクライアントの両方で実行可能なコンポーネントを作成できるようになる。これにより、重複するコードの記述を減らし、コードのメンテナンス性が向上する。
- SEOの向上
- サーバー側でコンテンツがレンダリングされるため、検索エンジンや大規模な言語モデルがコンテンツをクロールしやすくなり、SEO効果も向上する。
export default async function Page() {
const res = await fetch("https://api.example.com/products");
const products = await res.json();
return (
<div>
{products.map((product) => (
<p key={product.id}>{product.description}</p>
))}
</div>
);
}
上記のコードサンプルでは、Page
コンポーネントがサーバーでデータをフェッチし、そのデータを使って最初のレンダリング時に完全なHTMLをクライアントに送信している。これにより、クライアントでのデータフェッチや再レンダリングを行う必要がなくなるため、ページのロード時間が劇的に改善される。
新しいディレクティブ (Directives)
React 19では、サーバーコンポーネントの導入に伴い、コードの実行場所を明確にするためのディレクティブが追加された。この新しいディレクティブにより、サーバーとクライアントのどちらでコードが実行されるかを簡単に指定できるようになった。
'use client'
と 'use server'
デフォルトでは、React 19ではサーバーコンポーネントが使用されるため、クライアント側でのみ実行したいコードには'use client'
ディレクティブを追加する必要がある。一方、サーバー側でのみ実行する関数や処理には'use server'
ディレクティブを使用する。たとえば、クライアントコンポーネントで使用するフックは、'use client'
ディレクティブを用いることでクライアントのみで実行されることが保証される。
// クライアント側でのみ実行されるコンポーネント
'use client';
import { useState } from "react";
export default function TodoApp() {
const [items, setItems] = useState([{ text: "My first todo" }]);
async function formAction(formData) {
const newItem = formData.get("item");
setItems((items) => [...items, { text: newItem }]);
}
return (
<div>
<form action={formAction}>
<input type="text" name="item" placeholder="Add todo..." />
<button type="submit">Add</button>
</form>
<ul>
{items.map((item, index) => (
<li key={index}>{item.text}</li>
))}
</ul>
</div>
);
}
このコードは、クライアントでのイベント処理の一例であり、フォームデータを取得し、onSubmit
の代わりにアクションを使用して直接フォームのデータを処理している。
アクション (Actions)
React 19では、アクションという新しい概念が導入され、クライアントとサーバーの両方で使用できるようになった。これにより、フォームの送信やイベント処理がシンプルになり、サーバー側で直接データを処理することが可能になる。
たとえば、次のコードはサーバーアクションを使用してデータベースに新しいTodoアイテムを追加する例である。
'use server';
export async function createTodoItem(item) {
// サーバー側でデータベースに新しいアイテムを保存する処理
await db.todos.insert({ text: item });
}
クライアントからこのサーバーアクションを呼び出すことで、クライアント側では特定のAPIエンドポイントを作成することなく、サーバー側でデータベース操作が可能になる。
新しいフック (New Hooks)
React 19では、アクションと連携して使うための新しいフックがいくつか追加された。これにより、状態管理やフォームの送信処理がより直感的に行えるようになっている。
useActionState
このフックは、フォームの状態管理を簡素化し、フォームの送信時のバリデーションやエラー状態を処理するのに役立つ。さらに、pending
状態が公開され、アクションが実行中であることを示すローディングインジケーターを表示できる。
import { useActionState } from "react";
import { createUser } from "./actions";
export function Signup() {
const [state, formAction, pending] = useActionState(createUser, initialState);
return (
<form action={formAction}>
<label htmlFor="email">Email</label>
<input type="text" id="email" name="email" required />
{state?.message && <p aria-live="polite">{state.message}</p>}
<button aria-disabled={pending} type="submit">
{pending ? "Submitting..." : "Sign up"}
</button>
</form>
);
}
上記のコードでは、useActionState
フックを利用して、フォームの状態を簡単に管理し、フォーム送信中にローディングインジケーターを表示することができる。
その他の改善点
React 19には、他にも多くの改善点が含まれており、これらの改善点は開発者の生産性を向上させ、コードの可読性を高め、アプリケーションのパフォーマンスを向上させるものである。
リソースのプリロード (Preloading Resources)
React 19では、ページのロードパフォーマンスを向上させるために、リソースを事前に読み込むための新しいAPIが導入された。これにより、必要なスクリプトやスタイルシート、フォント、画像などをユーザーが要求する前に事前にロードすることが可能になる。
以下は、主なプリロード関連のAPIである:
prefetchDNS
: 接続する予定のドメインのDNS解決を事前に行う。preconnect
: リソースをリクエストする予定のサーバーに事前接続を行う。preload
: 予め使用することが予想されるスタイルシートやフォント、画像、外部スクリプトを事前に読み込む。preinit
: スクリプトの事前評価やスタイルシートの挿入を行う。
次のコード例では、これらのAPIを使ってリソースをプリロードし、パフォーマンスを最適化している。
import { prefetchDNS, preconnect, preload, preinit } from "react-dom";
preinit("https://example.com/script.js", { as: "script" });
preload("https://example.com/font.woff", { as: "font" });
preload("https://example.com/style.css", { as: "style" });
prefetchDNS("https://example.com");
preconnect("https://example.com");
このコードは、クライアント側で使用するスクリプトやフォント、スタイルシートをあらかじめブラウザに読み込ませるため、実際のページロード時の待機時間を短縮する役割を果たす。
ref
をプロパティとして使用する (ref as a prop)
React 19では、従来のforwardRef
を使用せずに、ref
をプロパティとして直接渡すことができるようになった。これにより、ref
を使ったコンポーネントのコードがシンプルになり、可読性が向上する。
function CustomInput({ placeholder, ref }) {
return <input placeholder={placeholder} ref={ref} />;
}
const ref = React.createRef();
<CustomInput ref={ref} />;
このように、ref
をプロパティとして扱うことで、従来のようにforwardRef
を使用する必要がなくなり、コードが簡潔になる。
useDeferredValue
の初期値オプション
React 19では、useDeferredValue
にinitialValue
オプションが追加された。これにより、初期レンダリング時に指定された値が使用され、その後バックグラウンドで再レンダリングがスケジュールされ、deferredValue
が返される。
function Search({ deferredValue }) {
const value = useDeferredValue(deferredValue, "initial value");
return <Results value={value} />;
}
この機能は、初期レンダリング時に値を表示しつつ、その後のデータ更新を非同期で行いたい場合に非常に便利である。
ドキュメントメタデータのサポート (Document metadata support)
React 19では、タイトルやメタタグ、リンクタグをネストされたコンポーネント内から直接レンダリングできるようになった。これにより、外部ライブラリやサードパーティ製のソリューションに依存せずに、SEOに対応したメタデータ管理が可能になる。
function BlogPost({ post }) {
return (
<>
<title>{post.title}</title>
<meta name="author" content="Jane Doe" />
<meta name="keywords" content={post.keywords} />
</>
);
}
このコードでは、Reactコンポーネント内からメタデータが簡単に挿入されており、従来のHelmet
などのライブラリに頼る必要がなくなっている。
スタイルシートのサポート (Stylesheet support)
React 19では、スタイルシートのロード順序を制御できるprecedence
オプションが追加された。このオプションにより、スタイルシートをコンポーネントに近い場所に配置し、実際に使用されるときにのみロードされるように設定できる。
さらに、同じスタイルシートが複数の場所で使用されている場合でも、重複してロードされることはない。また、サーバーサイドレンダリング時には、スタイルシートが<head>
タグに含まれ、ブラウザが適切なタイミングで描画を行うように制御される。
function ComponentOne() {
return (
<Suspense fallback="loading...">
<link rel="stylesheet" href="one.css" precedence="default" />
<link rel="stylesheet" href="two.css" precedence="high" />
</Suspense>
);
}
このコードでは、複数のスタイルシートがレンダリングされる順序を制御し、必要に応じて適切にロードされるように設定している。
非同期スクリプトのサポート (Async scripts support)
React 19では、非同期スクリプトをコンポーネントに近い場所で簡単にレンダリングできるようになった。これにより、非同期スクリプトが使用されるタイミングでのみロードされ、重複することなく効率的に扱われる。
function Component() {
return <script async={true} src="https://example.com/script.js" />;
}
このコードは、スクリプトを非同期に読み込むことで、ページのパフォーマンスを向上させると同時に、スクリプトの重複を避けている。
カスタム要素のサポート (Custom Elements support)
React 19は、Web Components仕様に基づいて、カスタム要素をフルサポートしている。これにより、独自のHTML要素を定義し、Reactコンポーネント内で簡単に使用することができるようになった。
カスタム要素のサポートにより、これまでReactでカスタム要素を扱う際に発生していた問題が解消され、外部のWeb ComponentsとReactをシームレスに統合できるようになっている。
エラーレポートの改善 (Better error reporting)
React 19では、エラーメッセージの重複が解消され、同じエラーが複数回表示されることがなくなった。また、エラーメッセージに修正方法や詳細な情報が追加され、開発者が問題を特定しやすくなっている。
例えば、React 18ではハイドレーションエラーが複数回報告されていたが、React 19ではエラーが1回だけ表示され、解決方法がわかりやすく提供される。
このように、React 19のエラーハンドリングは大幅に改善され、開発中のトラブルシューティングがより簡単になっている。
これらの改善点により、React 19は開発者にとってより強力で効率的なツールとなり、パフォーマンスの向上やUXの最適化が期待される。詳細は[What’s new in React 19 – Vercel」を参照していただきたい。