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

React Native 0.71: デフォルトでTypeScript、Flexbox Gapなど…

·13分で読めます
Matt Carroll
Matt Carroll
Meta社 デベロッパーアドボケイト
Nick Gerleman
Nick Gerleman
ソフトウェアエンジニア @ Meta
Nicola Corti
Nicola Corti
ソフトウェアエンジニア @ Meta
Lorenzo Sciandra
Lorenzo Sciandra
シニアソフトウェアエンジニア @ Microsoft

本日、React Native バージョン 0.71をリリースします!これは機能満載のリリースで、以下が含まれます。

この記事では、0.71のハイライトをいくつかご紹介します。

情報

変更点の全リストについては、CHANGELOG.mdをご確認ください。

TypeScriptがデフォルトに

このリリースでは、React NativeのTypeScript体験に力を入れています。

0.71以降、React Native CLIで新しいReact Nativeアプリを作成すると、デフォルトでTypeScriptアプリが作成されます。新しいプロジェクトにはすでにtsconfig.jsonがセットアップされているため、すぐにIDEが型付けされたコードの作成をサポートします。

また、react-nativeパッケージから直接、より正確な組み込みのTypeScript宣言も提供しています。これにより、@types/react-nativeは不要になり、型はReact Nativeのリリースと同期して更新されます。

最後に、すべての例でTypeScriptを使用するようにドキュメントが更新されました。

React Native 0.71にアップグレードした後、package.jsondevDependenciesから@types/react-nativeを削除することをお勧めします。

この変更の詳細、移行手順、Flowユーザーへの影響については、以前の投稿TypeScriptのファーストクラスサポートをご確認ください。

Flexboxギャップでレイアウトを簡素化

React Nativeでは、Flexboxを使用して、異なる画面サイズに合わせてコンポーネントを柔軟にレイアウトできます。ブラウザはFlexboxプロパティのgaprowGap、およびcolumnGapをサポートしており、Flexbox内のすべてのアイテム間のスペース量を指定できます。

これらのプロパティはReact Nativeで長く要望されており、0.71ではピクセル値を使用して定義されたギャップの初期サポートが追加されました。将来のバージョンでは、パーセンテージなどのより多くの値のサポートを追加する予定です。

これがなぜ有用なのかを見るために、さまざまなサイズのカードを10px離して、親コンテナの端にぴったりと配置するレスポンシブなレイアウトを構築しようとしていると想像してみてください。子マージンでこのレイアウトを実現しようとすると、厄介になる可能性があります。

以下は、各子要素にmargin: 10スタイルを付与することから始めるレイアウトを示しています。

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin around them cause the boxes to have margin around all sides. On the right, the same diagram is shown highlighted to demonstrate the margin on all sides.

マージンはすべての子要素の端に均一に適用され、Flexboxの下では折りたたまれないため、カードの外側にスペースができてしまい、内部のスペースは目的の2倍になってしまいます。非均一なマージンを適用したり、親に負のマージンを使用したり、意図した間隔を半分にしたりすることでこれを回避できますが、はるかに簡単にできます。

フレックスギャップを使用すると、カードの内部に10ピクセルのギャップを作るために、コンテナにgap: 10を設定することでこのレイアウトを実現できます。

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin only on the inner sides and not the outer sides of the boxes due to the Flexbox gap property. On the right, the same diagram is shown highlighted to demonstrate the margin only on the inner sides.

Flexboxギャップの詳細については、CSS Tricksのこのブログ記事を参照してください。

アクセシビリティ、スタイル、イベントのためのWebにインスパイアされたprops

このリリースには、React NativeのAPIを多くのプラットフォーム間で整合させるために、Web標準にインスパイアされた多数の新しいpropsが含まれています。これらの新しいpropsは純粋に付加的なものであり、同等のアクセシビリティ、動作、またはスタイルpropsに対する移行や動作変更は想定されていません。

導入された新しいプロップエイリアスの場合、異なる名前の既存のプロップがあり、両方が指定されている場合、新しいエイリアスプロップ値が優先されます。たとえば、このリリースでは、Webのsrcプロップと整合させるために、Imageコンポーネントのsourcesrcプロップエイリアスが追加されています。srcsourceの両方が指定されている場合、新しいsrcプロップが使用されます。

React NativeをWeb標準に合わせるための背景については、この提案関連する議論をご確認ください。

アクセシビリティ

既存のReact NativeアクセシビリティプロパティのエイリアスとしてARIAプロパティを導入しました。

これらのプロパティは、React Nativeのすべてのコアコンポーネントに存在します: aria-labelaria-labelledbyaria-modalidaria-busyaria-checkedaria-disabledaria-expandedaria-selectedaria-valuemaxaria-valueminaria-valuenow、およびaria-valuetext

また、aria-hiddenaria-liverole、およびtabIndexについても同等のウェブ動作を導入しました。

詳細については、このIssueを参照してください。

コンポーネント固有の動作

コアコンポーネントについて、プロップ名を同等のDOMプロップ名と一致させるためのプロップも導入されました。

  • Image: alt, tintColor, crossOrigin, height, referrerPolicy, src, srcSet, および width
  • TextInput: autoComplete, enterKeyHint, inputMode, readOnly, および rows

詳細については、このIssueを参照してください。

スタイル

特定のCSSスタイルと整合させるために、以下のスタイルに機能拡張が施されました。

  • aspectRatioが文字列値に対応しました。
  • fontVariantがスペース区切りの文字列値に対応しました。
  • fontWeightが数値に対応しました。
  • transformが文字列値に対応しました。

既存のReact Nativeスタイルをシャドウするために、以下のエイリアスが追加されました。

詳細については、このIssueを参照してください。

イベント

最後に、PointerEventsのオプトイン実装も追加されました。

有効にすると、Viewの以下のハンドラーがホバーをサポートします。

  • onPointerOveronPointerOut
  • onPointerEnteronPointerLeave

これらのイベントはPressabilityにも実装されており、ホバーの新しいオプトインサポートを提供します。

これらの機能を有効にするには、以下のフラグをtrueに設定してください。

import ReactNativeFeatureFlags from 'react-native/Libraries/ReactNative/ReactNativeFeatureFlags';

// enable the JS-side of the w3c PointerEvent implementation
ReactNativeFeatureFlags.shouldEmitW3CPointerEvents = () => true;

// enable hover events in Pressibility to be backed by the PointerEvent implementation.
// shouldEmitW3CPointerEvents should also be true
ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover =
() => true;

AndroidおよびiOSネイティブ設定でReact機能フラグも有効にする必要があります。

詳細については、専用のPointerEventsの投稿をご確認ください。

PropTypesの復元

React NativeのViewPropTypesText.propTypesといったプロップ型は0.66で非推奨となり、これらにアクセスすると非推奨警告が出力されていました。0.68でこれらが削除された際、多くの開発者がReact Nativeの最新バージョンへのアップグレードでエラーを経験し始めました。

調査の結果、いくつかの問題がコミュニティによる非推奨警告への対処を妨げていたことが判明しました。第一に、非推奨警告が常に実行可能であるとは限らず、人々が無視してしまう原因となっていました(問題1問題2)。第二に、非推奨警告がLogBox.ignoreLogsによって誤ってフィルタリングされていたことです。これらは両方とも修正されましたが、非推奨の呼び出しサイトをアップグレードするために、より多くの時間を提供したいと考えています。

そこで、このリリースではReact NativeのpropTypesを再度追加し、人々がコードをアップグレードして使用を避けるための移行を容易にしました。deprecated-react-native-prop-typesパッケージも0.71のすべてのプロップに対応して更新されました。将来的には、非推奨化を進め、propTypesを再び削除する予定です。削除を再検討する際には、コミュニティが経験する問題が大幅に減少すると予想しています。

注意

この変更の一環として、LogBox.ignoreLogからのコンソールフィルタリングも削除します。これは、アップグレード時に以前Logbox.ignoreLogでフィルタリングしていたログがコンソールに再び表示されるようになることを意味します。

これは、非推奨の警告などのログを見つけて修正できるようにするため、想定されている動作です。

開発者エクスペリエンスの改善

React DevTools

このリリースでは、ウェブで人気のReact DevTools機能を2つ、React Nativeに導入しました。

"クリックで検査"は、React Dev Toolsの左上隅にあるオプションで、Chrome要素インスペクターと同様に、アプリ内のアイテムをクリックしてDev Toolsで検査できます。

コンポーネントのハイライト機能は、DevToolsで選択した要素をアプリ内でハイライト表示し、どのReactコンポーネントがどの画面上の要素に対応しているかを確認できます。

以下に、両方の機能が動作している様子を示します。

Video of the behavior described above in action. On the left is a React Native app running in an iPhone simulator. On the right is the React DevTools. In both workflows, clicking on an item in the DevTools highlights the corresponding components in the app.

Hermes

React Native 0.70で、HermesをReact Nativeのデフォルトエンジンにしました

React Native 0.71では、いくつかの注目すべき改善を加えてHermesをアップグレードしています。

  • ソースマップの改善: Metroでネットワーク経由でソースマップを読み込むことにより、Flipper以外で最近のバージョンのChrome Dev Toolsでソースマップを使用する機能が復元されました。
  • JSON.parseパフォーマンスの改善: このバージョンには、JSON.parseのパフォーマンスを最大30%向上させるパフォーマンス最適化が含まれています。
  • .at()のサポートを追加: Hermesは現在、StringTypedArray、およびArray.at()サポートしています。

変更点の全リストについては、Road to 71 issueを参照してください。

新しいアーキテクチャ

このリリースでは、これまでに収集したユーザーからのフィードバックとレポートに基づいて、実験的な新しいアーキテクチャ体験に多くの改善が加えられました。

  • ビルド時間の短縮: 新しい配布モデルはMaven Centralを使用しており、Androidでのビルド時間を大幅に短縮し、Windowsでの多くのビルド問題を解決し、新しいアーキテクチャでよりシームレスな体験を提供します。詳細はこちら
  • C++コードの削減: アプリにC++コードを追加することなく新しいアーキテクチャを有効にできるようになり、CLIアプリテンプレートからすべてのC++コードとCMakeファイルが削除されました。詳細はこちら
  • iOSアプリ設定のより良いカプセル化: iOSでは、Androidと同様のアプローチをとり、新しいアーキテクチャを設定するロジックのほとんどをRCTAppDelegateクラスにカプセル化しました。これにより、将来のアップグレードが簡素化され、手動での破壊的変更が少なくなります。
  • iOSでの依存関係管理の改善: ライブラリメンテナ向けに、パッケージのpodspec内で呼び出す新しいinstall_module_dependencies関数を追加しました。これにより、新しいアーキテクチャに必要なすべての依存関係がインストールされます。
  • バグ修正とIDEサポートの改善: AndroidのIDEサポートの改善など、ユーザーから新しいアーキテクチャワーキンググループに報告されたいくつかのバグと問題を修正しました。

繰り返しになりますが、新しいアーキテクチャは、導入を容易にするための変更を繰り返し行う中で、依然として実験的なAPI体験です。新しいアーキテクチャのドキュメントに記載されている新しい簡素化された手順を試してみて、フィードバックがあれば新しいアーキテクチャワーキンググループに投稿してください。

その他の注目すべき修正点

  • より良いスタックフレームの折りたたみ: React Nativeの内部フレームのリストを更新したため、LogBoxは内部のReact Nativeフレームではなく、より頻繁にあなたのコードを表示するようになり、問題のデバッグを迅速化します。
  • ビルド時間の改善: 現在のアーキテクチャと新しいアーキテクチャの両方でHermesのビルド時間(iOSとAndroidの両方)を改善するために、アセットをプレハブ用のMaven Centralに移行しました。
  • Androidテンプレートの改善: Androidテンプレートは大幅にクリーンアップされ、React Native Gradleプラグインに完全に依存するようになりました。設定手順はテンプレート内またはウェブサイトの新しい専用ページで直接見つけることができます。

破壊的変更

  • コンソールログの変更: LogBox.ignoreLogはコンソールログをフィルタリングしなくなりました。これは、LogBoxで非表示にしていたログがコンソールに表示されるようになることを意味します。詳細については、このコメントを参照してください。
  • AsyncStorageとMaskedViewIOSを削除: これらのコンポーネントはバージョン0.59から非推奨になっていたため、完全に削除する時が来ました。代替品については、これらのユースケースをカバーするコミュニティパッケージをReact Native Directoryで確認してください。
  • JSCRuntimeがreact-jscに移動: react-jsiがreact-jscとreact-jsiに分割されました。JSCRuntimeを使用する場合は、react-jscを依存関係として追加する必要があります(facebook/react-native@6b129d8)。

謝辞

このリリースは、70人以上のコントリビューターが1000以上のコミットを追加したおかげで実現しました。

特に、以下の主要なReact Nativeプロジェクトに貢献してくださった方々に感謝いたします。

最後に、このリリースをカットしてくれた@cortinico@kelset@dmytrorykun@cipolleschi、そして@titozzzに感謝します!

今すぐ0.71.0を試してみましょう!

React Native CLIユーザーの方は、既存のプロジェクトを更新する方法についてはアップグレードドキュメントを、新しいプロジェクトを作成するにはnpx react-native init MyProjectを使用してください。

React Nativeバージョン0.71は、Expo SDKバージョン48でサポートされます。

情報

0.71がReact Nativeの最新安定版となり、0.68.xバージョンはサポート対象外となりました。詳細については、React Nativeのサポートポリシーをご確認ください。