React Native 0.77 - 新しいスタイリング機能、Androidの16KBページ対応、Swiftテンプレート
本日、React Native 0.77のリリースを発表できることを嬉しく思います!
このリリースでは、いくつかの機能が提供されます。display: contents
、boxSizing
、mixBlendMode
、outline
関連プロパティなどの新しいスタイル機能により、より強力なレイアウトオプションを提供します。また、新しいAndroidデバイスとの互換性のためのAndroid 16KBページサポートも含まれます。さらに、コミュニティテンプレートをSwiftに移行して最新化するとともに、Objective-Cを好む開発者のためにObjective-Cとの互換性のサポートと維持を継続しています。
ハイライト
破壊的変更
ハイライト
より良いレイアウト、サイズ設定、ブレンドのための新しいCSS機能
React Native 0.77は、React NativeとWebを連携させるという目標をさらに推進します。アプリのレイアウト、サイズ設定、ブレンドをより細かく制御できる新しいCSSプロパティのサポートを追加しました。これらの変更は、複雑なレイアウトを簡素化し、テクスチャを追加し、アプリのアクセシビリティを向上させるのに役立ちます。
これらの新機能はすべて、新しいアーキテクチャでのみ利用可能です。
display: contents
によるシンプルなレイアウト
display: contents
プロパティは、要素がレイアウト構造から消滅しながら、その子要素が親要素の直接の子要素であるかのようにレンダリングされることを可能にします。これは、レイアウトに影響を与えずに子要素にスタイルを適用したい場合、イベントを処理する必要があるラッパーコンポーネントを構築する場合、またはShadowTreeと対話する必要がある場合に、スタイリング目的で役立ちます。
技術的に言えば、display: contents
はレイアウトボックスを生成せずに要素をレンダリングしますが、要素の子要素のレイアウトボックスは保持します。display: contents
を持つ要素は、ビュー階層から事実上フラット化されます。
ウィジェットが押されたときにアラートを表示したいこの例を見てみましょう。コンテナビュー内に赤いWidget
があります。
function Container() {
return (
<View style={styles.container}>
<Widget />
</View>
);
}
次に、実験的なポインタイベントを使用して、その下のコンポーネントが押されたときにユーザーに警告するという目的で、新しいAlerting
ラッパーコンポーネントを構築します。分かりやすくするために、このコンポーネントの背景は青色になっています。それは以下のコンポーネントのように見えるかもしれません。
function Alerting({children}) {
return (
<View
style={{backgroundColor: 'blue'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
}
function Container() {
return (
<View style={styles.container}>
<Alerting>
<Widget />
</Alerting>
</View>
);
}
これは私たちが望むものではありません。Alerting
は、子Widget
とは別に、独自の境界を持つ新しいレイアウトボックスを追加します。ラップしている要素のスタイルによっては、これは重大な視覚的および機能的変更をもたらす可能性があります。この例では、青い背景がタップに反応してアラートを出しますが、タップされたときに赤い「Hello World」ボックスだけがアラートを出すことを望んでいます。
Alerting
のView
ラッパーにdisplay: contents
を設定してもう一度試すと、ユーザーが元のWidget
の境界内で押した場合にのみアラートが表示されます。これは、Alerting
が独自のボックスを追加しなくなったものの、Widget
からバブルアップされたポインタイベントを観察できるためです。
function Alerting({children}) {
return (
<View
style={{display: 'contents'}}
onPointerDown={() => alert('Hello World!')}>
{children}
</View>
);
}
// ... function Container ...
ボックスサイジング
boxSizing
プロパティは、要素の様々なサイズ指定プロパティ(width
、height
、minWidth
、minHeight
など)がどのように計算されるかを定義します。boxSizing
がborder-box
の場合、これらのサイズは要素のボーダーボックスに適用されます。content-box
の場合、要素のコンテンツボックスに適用されます。デフォルト値はborder-box
で、これはWebのデフォルト値とは異なります。このプロパティがどのように機能するかについて詳しく知りたい場合は、Webドキュメントが良い情報源です。
border-box
はこれまでずっとデフォルトであり、content-box
が追加されるまで唯一のboxSizing
値でした。デフォルトを変更すると、突然いくつかのレイアウトが壊れる互換性のない変更になったでしょう。後方互換性を確保するために、デフォルト値としてborder-box
を維持することにしました。
border-box
とcontent-box
の違いを理解するために、両方のView
にpadding: 20
とborderWidth: 10
が設定されている次の例を見てみましょう。border-box
を使用する場合、サイズ指定のためにボーダーとパディングを考慮します。content-box
を使用する場合、サイズ指定のためにコンテンツのみを考慮します。
CSS mixBlendMode
mixBlendMode
プロパティを使用すると、要素がスタッキングコンテキスト内の他の要素とどのように色をブレンドするかを制御できます。各ブレンド機能の完全な概要については、MDNドキュメントをご覧ください。
ブレンドするものをより細かく制御できるように、isolation
プロパティも追加しました。View
にisolation: isolate
を設定すると、そのView
はスタッキングコンテキストを強制的に形成します。したがって、このプロパティを一部の祖先View
に設定することで、mixBlendMode
を持つ一部の子孫View
が分離されたView
を超えてブレンドされないようにすることができます。
mixBlendMode値
normal
: 要素はブレンドされずに背景の上に描画されます。multiply
: ソースカラーがデスティネーションカラーと乗算され、デスティネーションを置き換えます。screen
: 背景とソースカラー値の補数を乗算し、結果の補数を取ります。overlay
: 背景カラー値に応じて色を乗算またはスクリーンします。darken
: 背景とソースカラーのうち、より暗い方を選択します。lighten
: 背景とソースカラーのうち、より明るい方を選択します。color-dodge
: 背景色を明るくして、ソース色を反映させます。黒で描画しても変化はありません。color-burn
: 背景色を暗くして、ソース色を反映させます。白で描画しても変化はありません。hard-light
: ソースカラー値に応じて色を乗算またはスクリーンします。背景に強いスポットライトを当てたような効果です。soft-light
: ソースカラー値に応じて色を暗くしたり明るくしたりします。背景に拡散したスポットライトを当てたような効果です。difference
: 2つの構成色の中で明るい色から暗い色を減算します。exclusion
: 差分モードに似た効果を生み出しますが、コントラストが低くなります。hue
: ソースカラーのヒューと背景カラーの彩度と輝度を持つ色を作成します。saturation
: ソースカラーの彩度と背景カラーのヒューと輝度を持つ色を作成します。color
: ソースカラーのヒューと彩度、および背景カラーの輝度を持つ色を作成します。これにより、背景のグレースケールが保持され、モノクロ画像を色付けしたり、カラー画像に色調を与えたりするのに便利です。luminosity
: ソースカラーの輝度と背景カラーのヒューと彩度を持つ色を作成します。これにより、カラーモードとは逆の効果が得られます。
アウトラインプロパティ
outlineWidth
、outlineStyle
、outlineSpread
、outlineColor
も導入しました。これらのアウトラインプロパティは、それぞれのborder
プロパティと非常によく似ていますが、パディングボックスの周りではなく、ボーダーボックスの周りにレンダリングされます。これらのプロパティにより、レイアウトに影響を与えることなく、要素のアウトラインを描画することで要素を強調表示できます。
詳細については、MDNドキュメントをご覧ください。
Androidバージョン15サポート & 16KBページサポート
Android 15での強制的なエッジツーエッジ表示
以前のリリースでは、Android 15のサポートに関して一部作業を行いました。Android 15における顕著な変更点の1つは、targetSdk
35でアプリをビルドした場合に、エッジツーエッジ表示が強制されることです。
まだこの問題を見ていない場合は、この問題を無視するとアプリのUIが破損する可能性があるため、以前の推奨事項を参照して、どのように対処すべきかを確認してください。
アプリでreact-native-safe-area-context
を使用している場合、このライブラリはすでに強制的なエッジツーエッジ表示を処理しています。
Androidの16KBページサイズ対応
Android 15では16KBメモリページサイズがサポートされ、アプリのパフォーマンス向上などが可能になりますが、これまでの4KBベースのアプリは将来のデバイスで互換性がなくなる可能性があります。これは現在、開発者が一部のデバイスでテストして、16KBページサイズがOSのデフォルトになることに備えるためのオプトイン機能です。
0.77リリースにより、React Nativeは16KBページサイズを完全にサポートする準備が整い、開発者はこれを使用して16KBデバイス向けアプリをテストおよびリリースできるようになります。
16KBサポートの詳細については、公式Android開発者サイトを参照してください。
コミュニティCLIとテンプレートの更新
コミュニティCLI: react-native init の非推奨化
このバージョンでは、React Native 0.75で導入されたreact-native init
コマンドの非推奨化が完全に完了します。
念のためですが、react-native init
コマンドはもう使用できません。代わりに次のいずれかを行う必要があります。
- Expoなどのフレームワークを使用し、新しいプロジェクトを作成するための専用コマンド
npx create-expo-app
を使用する npx @react-native-community/cli init
でコミュニティCLIを直接呼び出す
コミュニティCLI: Metroからの「iOS/Androidで実行」キーハンドラーの削除
このバージョンでは、Metroから「a」と「i」のキーボードショートカットを削除しました。これらのショートカットは、run-android
とrun-ios
コミュニティCLIコマンドを呼び出すために使用されていました。これらのキーボードショートカットは開発者エクスペリエンスを悪化させ、めったに使用されませんでした。さらに、フレームワークはターミナル出力を調整するのに適していると考えています。
この変更の詳細については、こちらの専用記事をご覧ください。
コミュニティテンプレート: iOSアプリのプログラミング言語としてのSwift
Expoを使用しているプロジェクトは、この変更の影響を受けないはずです。
この変更により、3つのファイル(main.m
、AppDelegate.h
、AppDelegate.mm
)を1つの新しいAppDelegate.swift
に置き換えることで、コミュニティテンプレートをスリム化できました。
これは技術的には破壊的変更です。アップグレードヘルパーでは、Objective-CからSwiftへの変更がこのように表示されます。
Swiftに移行する必要はありません。iOSコミュニティテンプレートのObjective-C++バリアントは引き続きサポートされています(ただし、RCTAppDependencyProvider
を統合する必要があることに注意してください)。新しいプロジェクトはiOSアプリ言語としてSwiftを使用して生成されますが、必要に応じてObjective-Cに戻すことも常に可能です。
制限事項
アプリにC++で記述されたローカルモジュールがある場合、このガイドに示されているように、それらをSwiftで登録することはできません。
アプリがこのカテゴリに該当する場合は、AppDelegateのSwiftへの移行をスキップし、アプリでObjective-C++を使い続けてください。
React Nativeのコアは、iOS、Android、その他のプラットフォーム間でのコード共有を促進するために、ほとんどC++を使用して開発されています。SwiftとC++の間の相互運用性は、まだ成熟しておらず安定していません。このギャップを埋め、Swiftにも移行できるようにする方法を検討しています。
RCTAppDependencyProvider
React Native 0.77では、アプリがサードパーティの依存関係をロードする方法がわずかに変更されています。これはコミュニティテンプレートの新しい行であり、見落とすとランタイムの問題を引き起こす可能性があります。必ずアプリに追加してください。
同等のObjective-Cの行は次のとおりです。
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"<Your app Name>";
self.dependencyProvider = [RCTAppDependencyProvider new];
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
// remaining of the AppDelegate
破壊的変更
Metroでのconsole.log()
ストリーミングの削除
React Nativeのデバッグのあらゆる側面が信頼性をもって動作し、最新のブラウザツールの機能と一致することを望んでいます。この品質基準を満たすため、0.76で非推奨化されたMetro経由のログ転送は、0.77で削除されます。
この統合は、デバイス上のデバッグターゲットと通信するためのカスタムアプローチに依存していました。この変更により、私たちはChrome DevTools Protocol (CDP)にのみ移行します。
- JSログを表示するには、React Native DevToolsとその充実したコンソールパネルを使用してください。このパネルは、ログフィルタリング、豊富なオブジェクト検査、ライブ式などをサポートしています。
- また、Expo ToolsやRadon IDEなどのサードパーティ製拡張機能を使用して、VS CodeをCDPデバッガーとして接続することもできます。
- これらの統合は、Reactチームによって直接サポートされているわけではありませんのでご注意ください。しかし、2025年にはファーストパーティのVS Codeサポートに取り組んでいます。
- ExpoはExpo CLIでログストリーミングを提供し続けています。
詳細については、JavaScriptログがMetroから離れるのはなぜですか?を参照してください。
その他の破壊的変更
全般
- アニメーション
- ネイティブのループアニメーションは、ループが終了するたびにReactの状態更新を送信しません。
- レイアウト
ScrollView
上の固定ヘッダーのposition
が考慮されるようになりました。- 絶対位置指定の動作がより準拠するようになりました
- JSモジュール
ReactFabricInternals
モジュールを削除- これはもうアクセスできません
- ネイティブモジュール
NativeModules
オブジェクトを使用して、JSでターボモジュールをロードできるようになりました。- これにより、ネイティブモジュールとターボネイティブモジュールの互換性が向上します。
- パッケージ
- dev-middleware: フレームワークはミドルウェアホストに対する
serverBaseUrl
を指定する必要があります
- dev-middleware: フレームワークはミドルウェアホストに対する
- APIの変更
AppRegistry
からuseConcurrentRoot
の型を削除しました。これはすでに無視されていたためです。NativeMethods
TypeScript定義からrefs
プロパティを削除しました。
- UXの変更
- 開発サーバーのキーコマンドから「iOSで実行」と「Androidで実行」を削除しました。
Android
- Kotlin
- これは、Kotlin 2.0.21に対してビルドされるReact Nativeの最初のバージョンです。Kotlin 2.0での変更点については、言語リリースノートで詳しく読むことができます。
- APIの変更
- ヌラビリティ
ReadableArray
内の非プリミティブゲッターがオプションとして正しく型付けされるようになりましたReactHost.createSurface()
メソッドを非nullableにする
- 名前の変更
DevSupportManagerBase.getCurrentContext()
をDevSupportManagerBase.getCurrentReactContext()
に変更
- ヌラビリティ
さらに、いくつかのAPIが削除または可視性が制限されたため、アクセスできなくなりました。これらのAPIは内部のものであり、React Native開発者が直接必要とするものではありませんでした。完全なリストは以下のとおりです。
削除されたAndroid APIのリスト
以下のパッケージは現在内部化されており、アクセスできません。
com.facebook.react.views.progressbar
com.facebook.react.views.safeareaview
com.facebook.react.modules.accessibilityinfo
com.facebook.react.modules.appstate
com.facebook.react.modules.clipboard
com.facebook.react.modules.devmodule
com.facebook.react.modules.reactdevtoolssettings
com.facebook.react.views.unimplementedview
以下のクラスは現在内部化されているか、削除されているため、アクセスできません。
BackHandler.removeEventListener
BaseViewManagerInterface
BindingImpl
CompositeReactPackage
DebugOverlayTags
DefaultDevSupportManagerFactory
からのメソッドcreate()
DevToolsReactPerfLogger
FabricComponents
ImageStoreManager
InteropModuleRegistry
NativeModulePerfLogger
NoopPrinter
NotThreadSafeViewHierarchyUpdateDebugListener
OkHttpCallUtil
PrinterHolder
Printer
ReactDebugOverlayTags
ReactNativeFlipper
ReactViewBackgroundManager
ReactViewGroup.getBackgroundColor()
ReactVirtualTextShadowNode
ReactVirtualTextViewManager
SimpleSettableFuture
SwipeRefreshLayoutManager
TaskCompletionSource
- DefaultReactHost.getDefaultReactHost()からのパラメータ
jsBundleLoader
iOS
- APIの変更
- 削除
RCTConstants.RCTGetMemoryPressureUnloadLevel
partialBatchDidFlush
RCTRuntimeExecutor
UseNativeViewConfigsInBridgelessMode
- 適切な機能フラグに置き換えられました
UseTurboModuleInteropForAllTurboModules
- TMsではInteropレイヤーが常に有効になっています。
- 変更点
CGColorRef
の使用をUIColor
に置き換え
- 削除
RCTAppDelegate
は、サードパーティの依存関係をロードするためにRCTDependencyProvider
を使用する必要があるようになりました。- CocoaPodsは、コンパイルの問題を避けるために、すべてのサードパーティの依存関係にC++バージョンを設定します。
React 19?
React 19は2024年12月6日にリリースされました。当時、React Native 0.77のブランチはすでにカットされており、React Native 0.77のRCを3つリリース済みでした。React Native 0.77のリリースでは、React 19を導入するには遅すぎました。
React 19はReact Native 0.78で提供される予定で、このバージョンのブランチはすでにカットされています。次のコマンドで新しいアプリを作成して試すことができます。
npx @react-native-community/cli init YourReact19App --version 0.78.0-rc.0
謝辞
React Native 0.77には、161人の貢献者による1061件を超えるコミットが含まれています。皆様の多大なご協力に感謝いたします!
このリリース投稿で機能のドキュメント作成に協力してくださった追加の著者の方々にも感謝します
- Jakub Piasecki氏、
display: contents
機能への貢献に感謝します。 - Nick Gerleman、Joe Vilches、Jorge Cabiedes Acostaの各氏に、新しいスタイル機能のリリースに感謝します。
- Alan Lee氏に、Android 16KBページサポートのコンテンツに感謝します。
- Riccardo Cipolleschi氏とOskar Kwaśniewski氏に、テンプレートのSwiftへの移行をサポートしていただいたことに感謝します。
- Nicola Corti氏に、
react-native init
の非推奨化サイクルコンテンツに感謝します。 - Alex Hunt氏に、Metroからの
console.log
の削除に関するコンテンツに感謝します。
0.77へのアップグレード
既存のプロジェクトのReact Nativeバージョン間のコード変更を確認するには、アップグレードドキュメントに加えて、React Nativeアップグレードヘルパーを使用してください。
新しいプロジェクトを作成するには
npx @react-native-community/cli@latest init MyProject --version latest
Expoをご利用の場合、React Native 0.77はExpo SDK 52でサポートされます(Expoプロジェクト内でReact Nativeを0.77.0にアップデートする方法については、近い将来、別のExpoブログ記事で発表されます)。
0.77がReact Nativeの最新の安定バージョンとなり、0.74.xはサポート対象外となります。詳細については、React Nativeのサポートポリシーをご覧ください。0.74の最終的なサポート終了アップデートを近い将来公開する予定です。