メインコンテンツへスキップ

React Native 0.78 - React 19など

·11分で読めます
Vojtech Novak
Vojtech Novak
ソフトウェアエンジニア @ Expo
Shubham Gupta
Shubham Gupta
ソフトウェアエンジニア @ Dream11
Fabrizio Cucci
Fabrizio Cucci
ソフトウェアエンジニア @ Meta
Riccardo Cipolleschi
Riccardo Cipolleschi
ソフトウェアエンジニア @ Meta

本日、React Native 0.78のリリースを発表できることを嬉しく思います!

このリリースでは、React NativeにReact 19が搭載され、その他にもAndroid Vector Drawableのネイティブサポートや、iOSのブラウンフィールド統合の改善など、いくつかの重要な機能が含まれています。

ハイライト

ハイライト

React 19

React 19がReact Nativeで利用可能になりました!

React 19ではReact 18からいくつかの変更が導入されているため、アプリの更新が必要です。例えば、propTypesのような一部のAPIが削除されたため、新しいバージョンのReactと互換性を持たせるためにアプリを調整する必要があります。

アプリをReact 19にアップグレードするには、ステップバイステップのアップグレード手順に従ってください。

移行後には、Reactのすべての新機能(これらに限定されません)を活用できるようになります。

  • Actions: これらは非同期トランジションを使用する関数です。非同期トランジションは、データの送信を自動的に管理します。保留状態、楽観的更新、エラー処理などを扱います。
  • useActionState: Actionsの上に構築されたユーティリティフックです。関数を受け取り、呼び出すためのラップされたActionを返します。アクションが呼び出されると、Actionの最後の結果とそのpending状態を返します。
  • useOptimistic: 非同期リクエストが進行中に、更新の最終状態を楽観的に表示するのを簡素化する新しいフックです。リクエストがエラーになった場合、Reactは自動的に以前の値に戻します。
  • use: これはレンダリング中にリソースへのアクセスを可能にする新しいAPIです。useを使ってPromiseやコンテキストを読み取ることができ、それらが解決されるまでReactはサスペンドします。
  • propsとしてのref: 他のpropと同様に、refpropとして渡せるようになりました。関数コンポーネントはもはやforwardRefを必要とせず、今すぐコンポーネントを移行できます。
  • その他多数

利用可能な新機能の完全なリストについては、React 19リリースブログ投稿をご覧ください。

React Compiler

React Compilerは、メモ化を自動的に適用することでReactアプリケーションを最適化するために設計されたビルド時ツールです。開発者はuseMemouseCallbackReact.memoなどのAPIを手動で使用して、アプリの変更されていない部分の不要な再計算を防ぐことができますが、これらの最適化を忘れたり誤用したりすることもありました。React Compilerは、JavaScriptとReactのルールの理解を活用して、コンポーネントやフック内の値または値のグループを自動的にメモ化することで、この問題に対処します。

このリリースでは、React NativeアプリでReact Compilerを有効にするプロセスを簡素化しました。以前のバージョンでは、コンパイラとそのランタイムの2つのパッケージをインストールする必要がありました。これらのパッケージをインストールした後、Metroを通じてReact Compilerを有効にするためにBabelプラグインを設定する必要がありました。

現在では、コンパイラ自体をインストールし、Babelプラグインを設定するだけで済みます。有効にする方法については、ステップバイステップのガイドに従ってください。

コンパイラが実行されていることを確認するには、React Native DevToolsを開きます。メモ化されたコンポーネントには、コンポーネントインスペクタでMemo ✨タグが付いているのが確認できるはずです。

React Compilerについてさらに詳しく知りたい場合は、以下のリソースが役立ちます。

より小さく、より速いリリースに向けて

2025年には、安定版のReact Nativeリリースをより頻繁に出荷するために、リリースプロセスを更新しています。

破壊的変更の数を減らすことで、React Nativeのバージョンアップがより簡単になります。リリースの高速化は、内部でリリースするすべてのバグ修正がより早く皆さんに届くことを意味し、React Native内部で開発する最新機能の恩恵を受けることができます。

この新しいモデルは、React Nativeエコシステムのすべての開発者に利益をもたらすと信じています。なぜなら、破壊的変更が少ないということは、誰もが信頼できる、より安定したフレームワークを意味するからです。

MetroでのJavaScriptログのオプトイン

Metro開発サーバー経由でのJavaScriptログストリーミングを復元するためのオプトインを追加しました。これは、0.77でCommunity CLIユーザー向けに削除された機能です。これは、ユーザーからのフィードバックに応え、また現在の代替機能の状況をレビューした結果です。

オプトインするには、新しい--client-logsフラグを使用します。利便性のために、npmスクリプトを介してエイリアスを設定することもできます。

npx @react-native-community/cli start --client-logs

Metroでのログストリーミングは将来的に廃止される予定であり、デフォルトではオフのままです。しかし、開発者がこの変更に適応するためのより長い移行期間を提供する予定です。

この更新は、近日公開の0.77.1マイナーリリースでも利用可能になります。

Android XMLドローアブルのサポートを追加

React Native 0.78では、Androidでアイコン、イラスト、その他のグラフィック要素をXMLリソースとして読み込む新しい方法を提供します。これにより、ベクタードローアブルを使用して、品質を損なうことなく任意のスケールでベクター画像を表示したり、シェイプドローアブルを使用してより基本的な装飾を描画したりできます。これはすべて、皆さんがよく知っているImageコンポーネントでサポートされています。この機能を今すぐ使用するには、sourceプロパティで参照することで、他の静的リソースと同様にXMLリソースをインポートできます。さらに、ビットマップではなくXMLリソースを使用することで、アプリケーションサイズを削減し、異なるDPIの画面でより良いレンダリング結果を得ることができます。

// via require
<Image
source={require('./img/my_icon.xml')}
style={{width: 40, height: 40}}
/>;

// or via import
import MyIcon from './img/my_icon.xml';
<Image source={MyIcon} style={{width: 40, height: 40}} />;

パフォーマンスと品質

他のすべての画像タイプと同様に、AndroidのXMLリソースはメインスレッド外で読み込まれ、展開されるため、フレーム落ちが発生しません。これは、リソースが即座に表示される保証はないものの、リソースの読み込み中にユーザー入力を妨げないことを意味します。オフスレッドデコーディングは、多数のアイコンを同時にレンダリングする必要がある場合に特に重要です。内部アプリでは、Androidのベクタードローアブルを使用することで、いくつかの大幅なパフォーマンス改善が実現しました。

ベクタードローアブルのようなリソースタイプを利用することは、品質を損なわずに画像を表示するのに最適な方法であり、画面密度ごとに画像タイプを含める必要がないため、APKファイルが小さくなる結果にもつながります。さらに、ベクタードローアブルは一度読み込まれるとメモリからコピーされるため、同じアイコンを複数回レンダリングしても、すべてが同時に表示されます。

トレードオフ

ドローアブルXMLリソースは完璧ではなく、使用には制約があることに注意することが重要です。

  • Androidアプリケーションのビルド時に参照する必要があります。これらのリソースは、Android Asset Packaging Tool (AAPT) を使用したビルドステップに渡され、生のXMLがバイナリXMLに変換されます。Androidは生のXMLファイルの読み込みをサポートしていません。これは既知の制限です。
  • Metro経由でネットワークから読み込むことはできません。XMLリソースのディレクトリや名前を変更した場合は、その都度Androidアプリケーションを再ビルドする必要があります。
  • 寸法がありません。デフォルトでは0x0のサイズで表示されるため、表示させるには幅と高さを指定する必要があります。
  • ランタイムで完全にカスタマイズできるわけではありません。寸法や全体のティントカラーは制御できますが、ストローク幅、境界線の半径、色など、リソース*内部*の個々の要素属性をカスタマイズすることはできません。これらのタイプのカスタマイズには、XMLリソースの異なるバリアントが必要です。
情報

Androidのベクタードローアブルは、react-native-svgのようなライブラリの1対1の代替ではありません。これらはAndroid専用に設計されており、iOSでは動作しません。すべてのプラットフォームで同じSVGを使用したい場合は、引き続きreact-native-svgを使用する必要があります。ベクタードローアブルは、カスタマイズ性を犠牲にしてパフォーマンス上の利点を提供するにすぎません。

iOSでのReactNativeFactory

React Native 0.78では、iOSでのReact Nativeの統合を改善しました。

このバージョンでは、AppDelegateを必要とせずにReact Nativeのインスタンスを作成できる新しいクラスRCTReactNativeFactoryが導入されました。これにより、例えばViewController内で新しいReact Nativeのバージョンを作成できるようになります。これは、ブラウンフィールドアプリとの統合を劇的に簡素化します。

アプリのViewController内にReact Nativeのビューを表示したいとします。React Native 0.78からは、このガイドに示されているようにすべての依存関係をインストールした後、このコードを追加するだけです。


+import React
+import React_RCTAppDelegate

public class ViewController {

+ var reactNativeFactory: RCTReactNativeFactory?
+ var reactNativeDelegate: ReactNativeDelegate?

public func viewdidLoad() {
super.viewDidLoad()
// …
+ reactNativeDelegate = ReactNativeDelegate()
+ reactNativeFactory = RCTReactNativeFactory(delegate: reactNativeDelegate!)
+ view = reactNativeFactory.rootViewFactory.view(withModuleName: "<your module name>")
}

}

+class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {

+ override func sourceURL(for bridge: RCTBridge) -> URL? {
+ self.bundleURL()
+ }
+
+ override func bundleURL() -> URL? {
+ #if DEBUG
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+ #else
+ Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+ #endif
+ }
+}

React Nativeは、そのViewControllerにナビゲートするとすぐに読み込まれます。

このコードは、RCTReactNativeFactoryを作成し、それにデリゲートを割り当て、React Nativeのビュー用のrootViewを作成するように要求します。

デリゲートは以下で定義されており、sourceURLbundleURLプロパティをオーバーライドして、ビューに読み込むJSバンドルをどこで見つけられるかをReact Nativeに伝えます。

その他の破壊的変更

全般

  • React Native DevTools
    • FuseboxClient CDPドメインを削除
  • Codegen
    • コンポーネントの配列型とコマンドの配列型を分離

Android

  • Null許容性の変更: RootViewをKotlinに移行した結果、パラメータの型がnull許容から非null許容に変更されました。
  • 以下のクラスは、publicからinternalに移動されたか、削除されたため、もはやアクセスできません。
    • com.facebook.react.bridge.GuardedResultAsyncTask
    • com.facebook.react.uimanager.ComponentNameResolver
    • com.facebook.react.uimanager.FabricViewStateManager
    • com.facebook.react.views.text.frescosupport.FrescoBasedReactTextInlineImageViewManager

iOS

  • Imageのloadイベントのサイズ情報を論理サイズからピクセルに変更(これは旧アーキテクチャにのみ影響します)

謝辞

React Native 0.78には、87人のコントリビューターによる509件以上のコミットが含まれています。皆様の多大な貢献に感謝します!

このリリース投稿で機能のドキュメント作成に協力してくださった追加の著者の方々にも感謝します

  • Dream11チームによるReact NativeでのReact 19機能の徹底的なテスト
  • Nicola CortiによるFaster Releasesへの取り組み
  • Alex HuntによるMetroログのオプトインへの取り組み
  • Peter AbbondanzoによるAndroid XML Drawableサポートへの取り組み
  • Oskar KwaśniewskiによるReactNativeFactoryへの取り組み

0.78へのアップグレード

既存のプロジェクトについては、アップグレードのドキュメントに加えて、React Native Upgrade Helperを使用してReact Nativeのバージョン間のコード変更を確認してください。

新しいプロジェクトを作成するには

npx @react-native-community/cli@latest init MyProject --version latest

Expoを使用している場合、React Native 0.78はExpo SDKのカナリアリリースでサポートされる予定です

情報

0.78は現在React Nativeの最新安定版となり、0.75.xはサポート対象外となります。詳細については、React Nativeのサポートポリシーをご覧ください。近い将来、0.75の最終的なサポート終了アップデートを公開する予定です。