OpenAIReact Native2025/01/21 0:00

React Native 0.77 - New Styling Features, Android’s 16KB page support, Swift Template

要点だけを先に読めるように短く再構成したセクションです。

元記事

Quick Digest

要約

要点だけを先に読めるように短く再構成したセクションです。

openaijamodel: gpt-5-mini-2025-08-07

React Native 0.77 リリース概要 — 新しいスタイル機能、Android 16KB 対応、iOSテンプレートをSwift化

Key Points

  • 新しいCSSプロパティ追加
  • Android 16KB ページ対応
  • iOSテンプレートをSwift化

Summary

React Native 0.77 が公開されました。新しいスタイル関連プロパティ(display: contents、boxSizing、mixBlendMode、outline*)や、Androidの16KBページサイズ対応、iOSコミュニティテンプレートをSwiftに移行する変更などが含まれます。一部機能はNew Architecture限定です。開発ワークフローやテンプレートの変更点に注意してアップグレードしてください。

Key Points

  • 新しいCSS互換プロパティ(display: contents / boxSizing / mixBlendMode / outlineWidth/outlineStyle/outlineSpread/outlineColor)を追加。複雑なレイアウトやブレンド表現が可能に。※New Architecture限定。
  • boxSizing のデフォルトは従来通り border-box。content-box は選択可能。
  • Android: Android 15 の強制 edge-to-edge 表示への対応と、16KB メモリページサイズのサポートを追加。将来のデバイス互換性の確認が必須。
  • Community CLI/テンプレートの変更:react-native init の廃止完了(npx @react-native-community/cli init または Expo を推奨)、Metro の 'a' / 'i' キーハンドラ削除。
  • iOS コミュニティテンプレートはデフォルトで Swift に。Objective-C++ は引き続きサポート。ただし C++ ローカルモジュールがある場合は Swift への移行を避けるべき。
  • テンプレートに RCTAppDependencyProvider の設定が必須に。見落とすとランタイム問題が発生する可能性あり。
  • Metro の console.log() ストリーミングが削除される破壊的変更あり。デバッグフローを確認すること。

Upgrade notes (短く実務向け)

  • New Architecture を有効にしていない場合、今回のCSS機能は利用できない点に注意。
  • iOS: 新規プロジェクトは Swift で生成されるため、既存 Objective‑C++ を維持するなら手動で差し替え/継続を検討。
  • C++ ベースのネイティブモジュールがある場合は AppDelegate を Objective‑C++ のままにし、RCTAppDependencyProvider を追加すること。
  • Metro を使ったワークフローで 'a'/'i' ショートカットや console.log() ストリーミングに依存している場合は代替コマンド/ツールに切替えを準備。
  • Android は 16KB ページサイズでの動作確認を実機または公式ドキュメントを参照して行う。

Full Translation

翻訳

原文の流れを保ったまま読める翻訳セクションです。

openaijamodel: gpt-5-mini-2025-08-07

React Native 0.77 — 新しいスタイリング機能、Androidの16KBページサポート、Swiftテンプレート

Today we are excited to release React Native 0.77! このリリースには複数の機能が含まれます:display: contents、boxSizing、mixBlendMode、outline 関連プロパティなどの新しいスタイリング機能により、より強力なレイアウトオプションを提供します。また、最新のAndroidデバイスと互換性を持たせるために Android の16KBページサポートを導入しました。さらに、コミュニティテンプレートを Swift に移行して近代化するとともに、Objective-C を好む開発者向けに互換性とサポートを継続します。

ハイライト

  • 新しい CSS 機能(レイアウト、サイズ指定、ブレンド向け)
  • Android バージョン15サポート & 16KBページサポート
  • Community CLI とテンプレートの更新

Breaking Changes

  • Metro における console.log() のストリーミングの削除

新しい CSS 機能 — レイアウト、サイズ指定、ブレンドの改善

React Native 0.77 は Web と React Native の整合性をさらに進めます。アプリのレイアウト、サイズ指定、ブレンドをより細かく制御するための新しい CSS プロパティを追加しました。これらの変更は複雑なレイアウトの簡素化、テクスチャ追加、アクセシビリティ向上に役立ちます。

注意: これらの新機能はすべて New Architecture のみで利用可能です。

display: contents による簡素化されたレイアウト

display: contents は、要素自体をレイアウト構造から“消しつつ”その子要素は親の直下にあるかのようにレンダリングさせるプロパティです。ラッパーコンポーネントで子要素にスタイルを適用したいがレイアウトに影響を与えたくない場合や、イベントを扱うラッパーを作るとき、ShadowTree とやり取りする必要がある場合に有用です。

技術的には、display: contents は要素のレイアウトボックスを生成せずに子要素のレイアウトボックスは保持します。display: contents を設定した要素は事実上ビュー階層から平坦化されます。

例:ウィジェットが押されたときにアラートを表示したいケース。コンテナ内に赤い Widget がある状況から始めます。

// Container.jsx
function Container() {
    return (
        <View style={styles.container}>
            <Widget />
        </View>
    );
}

次に、experimental な pointer events を使って、配下のコンポーネントが押されたときにユーザーにアラートを出す Alerting ラッパーを作ります。分かりやすくするためにこのコンポーネントの背景は青にしています。

// Container.jsx
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 が独自のレイアウトボックス(青い領域)を作るため、タップに反応する領域が想定より広くなってしまいます。Alerting の View に display: contents を設定すると、Alerting 自身のボックスを生成しなくなり、Widget からバブルしたポインターイベントのみを監視できるようになります。結果として元の Widget の境界内でのみアラートが発生します。

function Alerting({ children }) {
    return (
        <View style={{ display: 'contents' }} onPointerDown={() => alert('Hello World!')}>
            {children}
        </View>
    );
}

boxSizing

boxSizing プロパティは、要素の各種サイズプロパティ(width、height、minWidth、minHeight など)がどのように計算されるかを定義します。boxSizing が border-box の場合、これらのサイズは要素のボーダーボックスに適用されます。content-box の場合はコンテンツボックスに適用されます。デフォルト値は border-box です。これは Web のデフォルトとは異なります。詳細を知りたい場合は Web のドキュメントを参照してください。

警告: border-box がこれまでのデフォルトであり、content-box を追加するまでは唯一の boxSizing 値でした。デフォルトを変更すると破壊的変更となり多くのレイアウトが突然壊れるため、後方互換性を保つ目的で border-box をデフォルトのままにしています。

例:どちらの View も padding: 20 と borderWidth: 10 を持つ場合、border-box ではボーダーとパディングをサイズ計算に含めますが、content-box ではコンテンツのみをサイズ計算に含めます。

mixBlendMode

mixBlendMode プロパティは、要素が同じスタッキングコンテキスト内の他の要素とどのように色をブレンドするかを制御します。各ブレンド関数の詳細は MDN documentation を参照してください。また、より細かくブレンド範囲を制御するために isolation プロパティも追加しました。

  • isolation: isolate を View に設定すると、その View はスタッキングコンテキストを強制的に形成します。これにより、ある祖先 View に isolation を設定し、その内部で mixBlendMode を使う子要素が祖先の外にブレンドしないようにできます。

mixBlendMode の値(主要な説明を日本語で):

  • normal: ブレンドせず背景の上に描画します。
  • multiply: ソース色とデスティネーション色を乗算し、デスティネーションを置き換えます。
  • screen: 背景とソース色の補色を乗算して結果を補色します。
  • overlay: 背景色に応じて乗算またはスクリーンを適用します。
  • darken: 背景とソースのうち暗い方を選択します。
  • lighten: 背景とソースのうち明るい方を選択します。
  • color-dodge: 背景色をソース色に合わせて明るくします。黒で描画すると変化はありません。
  • color-burn: 背景色をソース色に合わせて暗くします。白で描画すると変化はありません。
  • hard-light: ソース色に応じて乗算またはスクリーンを適用します。強いスポットライトを当てたような効果です。
  • soft-light: ソース色に応じて暗くしたり明るくしたりします。拡散されたスポットライトのような効果です。
  • difference: 2色のうち暗い方を明るい方から減算します。
  • exclusion: Difference に似た効果を低コントラストで生成します。
  • hue: ソース色の色相と、背景の彩度・明度で色を生成します。
  • saturation: ソース色の彩度と、背景の色相・明度で色を生成します。
  • color: ソース色の色相・彩度と、背景の明度で色を生成します(グレーレベルを保持し、単色画像の着色に便利)。
  • luminosity: ソース色の明度と、背景の色相・彩度で色を生成します。Color モードとは逆の効果になります。

Outline プロパティ

outlineWidth、outlineStyle、outlineSpread、outlineColor を導入しました。これらは border 系プロパティと似ていますが、padding ボックスの周りではなく border ボックスの周りに描画されます。アウトラインを描画して要素をハイライトできますが、レイアウトには影響を与えません。詳細は MDN documentation を参照してください。

Android: バージョン15サポート & 16KBページサポート

Android 15 での強制 edge-to-edge

前リリースで Android 15 のサポートに向けた作業を既に行っています。Android 15 の目に見える変更の一つは、targetSdk 35 でアプリをビルドした場合に強制的に edge-to-edge 表示になる点です。まだ対応していない場合は、以前の推奨事項を確認してください。無視するとアプリの UI が壊れる可能性があります。

補足: react-native-safe-area-context を使用している場合、ライブラリ側で強制 edge-to-edge の処理を既に行っています。

Android の 16 KB ページサイズサポート

Android 15 は 16KB のメモリページサイズをサポートし、アプリのパフォーマンス向上を可能にしますが、従来の 4KB ベースのアプリは将来的なデバイスで互換性の問題が生じる可能性があります。現時点では開発者が特定デバイスでテストするためのオプトイン機能です。React Native 0.77 では 16 KB ページサイズをフルにサポートしており、開発者は 16 KB デバイス向けにテストおよびアプリの配布が可能になります。詳細は公式の Android Developers site を参照してください。

Community CLI とテンプレートの更新

Community CLI: react-native init の廃止完了

このバージョンで React Native 0.75 で導入された react-native init コマンドの廃止を完了します。つまり、react-native init コマンドは使用できなくなります。代わりに次のいずれかを使用してください:

  • フレームワーク(例: Expo)を使う場合: npx create-expo-app
  • Community CLI を直接呼ぶ: npx @react-native-community/cli init

Community CLI: Metro からの "run on iOS/Android" キーハンドラの削除

今回のリリースでは Metro から 'a' および 'i' のキーボードショートカットを削除しました。これらは run-android & run-ios の community CLI コマンドを呼び出すために使われていましたが、開発体験が悪く使用頻度も低かったため廃止しました。ターミナル出力の調整はフレームワーク側で行う方が適切だと考えています。詳しくはこの専用ポストを参照してください。

Community Template: iOS アプリのプログラミング言語を Swift に

補足: Expo を使っているプロジェクトはこの変更の影響を受けないはずです。

この変更により、コミュニティテンプレートをスリム化でき、main.m、AppDelegate.h、AppDelegate.mm の 3 ファイルを単一の新しい AppDelegate.swift に置き換えました。これは技術的には破壊的変更です。アップグレードヘルパーでは Objective-C から Swift への変更が表示されます。

Swift へ移行する必要はありません。iOS コミュニティテンプレートの Objective-C++ バリアントは引き続きサポートされます(ただし RCTAppDependencyProvider の統合は引き続き必要です)。新規プロジェクトはデフォルトで iOS の言語に Swift を使用して生成されますが、必要に応じて Objective-C に戻すこともできます。

制限事項

  • アプリに C++ で書かれたローカルモジュールがある場合、Swift 上でそれらを登録できないことがあります(詳細は guide を参照)。該当する場合は AppDelegate の Swift への移行をスキップし、Objective-C++ を使い続けてください。
  • React Native core は主に C++ で開発されており、iOS と Android 間でのコード共有を促進しています。Swift と C++ の相互運用性はまだ成熟しておらず安定していません。Swift への移行を可能にするための対応を検討中です。

RCTAppDependencyProvider

React Native 0.77 はサードパーティ依存関係の読み込み方法をわずかに変更しています。コミュニティテンプレートに入っている新しい行(RCTAppDependencyProvider)が抜けているとランタイムの問題になる可能性があります。アプリに必ず追加してください。Objective-C の等価コードは以下のとおりです。

// AppDelegate.mm
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.moduleName = @"";
    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

Breaking Changes

Metro における console.log() のストリーミングの削除

We want every aspect of React Native debugging to behave reliably and to match the functionality of modern