React Native 0.71:デフォルトでの TypeScript、Flexbox Gap など...
本日、React Native バージョン 0.71 をリリースしました!これは、次のような機能満載のリリースです。
- デフォルトでの TypeScript
- Flexbox Gap によるレイアウトの簡素化
- アクセシビリティ、スタイル、イベント用の Web に触発されたプロパティ
- PropTypes の復元
- 開発者エクスペリエンスの改善
- 新しいアーキテクチャの更新
この記事では、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.json の devDependencies
から @types/react-native
を削除することをお勧めします。
移行手順や Flow ユーザーへの影響など、この変更の詳細については、以前の投稿「TypeScript のファーストクラスサポート」を参照してください。
Flexbox gap によるレイアウトの簡素化
React Native では、Flexbox を使用して、さまざまな画面サイズでコンポーネントを柔軟にレイアウトできます。ブラウザーは、Flexbox プロパティ gap、rowGap、および columnGap をサポートしており、Flexbox 内のすべてのアイテム間の間隔の量を指定できます。
これらのプロパティは React Native で長らく要望されてきましたが、0.71 ではピクセル値を使用して定義されたギャップの初期サポートが追加されます。今後のバージョンでは、パーセンテージなどのより多くの値のサポートを追加する予定です。
これがなぜ便利なのかを理解するために、親コンテナーの端に接し、互いに 10px 離れた可変サイズのカードを使用したレスポンシブレイアウトを構築することを想像してみてください。子マージンを使用してこのレイアウトを達成しようとすると、複雑になる可能性があります。
以下は、各子に margin: 10
スタイルを適用することから始めるレイアウトを示しています。
マージンは、すべての子の端に均一に適用され、Flexbox の下で折りたたまれないため、カードの外側に間隔が与えられ、内部には目的のスペースの 2 倍のスペースが与えられます。均一でないマージンを適用したり、親に負のマージンを使用したり、目的の間隔を半分にしたりすることで、これを回避できますが、はるかに簡単にすることができます。
フレックスギャップを使用すると、コンテナーに gap: 10
を設定して、カードの内部の間に 10 ピクセルのギャップを設定することで、このレイアウトを実現できます。
Flexbox ギャップの詳細については、CSS Tricks のこのブログ記事を参照してください。
アクセシビリティ、スタイル、イベント用の Web に触発されたプロパティ
このリリースには、Web 標準に触発された多くの新しいプロパティが含まれており、React Native の API を多くのプラットフォームで調整します。これらの新しいプロパティは純粋に追加されるため、同等のアクセシビリティ、動作、またはスタイルプロパティの移行や動作の変更は想定されていません。
導入された新しいプロパティエイリアスについては、異なる名前の既存のプロパティがあり、両方が指定されている場合、新しいエイリアスプロパティ値が優先されます。たとえば、このリリースでは、Web 上の src
プロパティに合わせて Image コンポーネントの source
の src
プロパティエイリアスが追加されます。src
と source
の両方が指定されている場合は、新しい src
プロパティが使用されます。
React Native を Web 標準に合わせる背景の詳細については、この 提案 と 関連するディスカッション を参照してください。
アクセシビリティ
既存の React Native アクセシビリティプロパティのエイリアスとして ARIA プロパティを導入しました。
これらのプロパティは、React Native のすべてのコアコンポーネントに存在するようになりました:aria-label
、aria-labelledby
、aria-modal
、id
、aria-busy
、aria-checked
、aria-disabled
、aria-expanded
、aria-selected
、aria-valuemax
、aria-valuemin
、aria-valuenow
、および aria-valuetext
。
また、aria-hidden
、aria-live
、role
、tabIndex
について、同等のWebの動作を導入しました。
詳細については、このissueを参照してください。
コンポーネント固有の動作
コアコンポーネントのprop名を同等のDOM prop名に合わせるためのpropも導入されました。
- 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
の以下のハンドラーがホバーをサポートします。
onPointerOver
、onPointerOut
onPointerEnter
、onPointerLeave
これらのイベントは、ホバーの新しいオプトインサポートのために 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;
詳細については、専用のPointerEventsの投稿をご覧ください。
PropTypesの復元
React Nativeのpropタイプ(ViewPropTypes
やText.propTypes
など)は、0.66で非推奨となり、アクセスすると非推奨の警告が出力されていました。0.68で削除されたとき、多くの開発者が最新バージョンのReact Nativeへのアップグレード時にエラーを経験し始めました。
調査の結果、いくつかの問題によりコミュニティが非推奨の警告に対処できなかったことがわかりました。まず、非推奨の警告は必ずしも実行可能なものではなかったため、人々が無視していました(問題1、問題2)。次に、非推奨の警告は、LogBox.ignoreLogs
によって誤ってフィルタリングされていました。これらは両方とも修正されましたが、非推奨のコールサイトをアップグレードするための時間を増やしたいと考えています。
そこで、今回のリリースでは、React NativeのpropTypesを追加し、人々がコードをアップグレードおよび移行して使用を避けることを容易にしました。deprecated-react-native-prop-types
パッケージも、0.71のすべてのpropについて更新されています。将来的には、非推奨を続行し、propタイプを再度削除する予定です。削除を再検討するときには、コミュニティが経験する問題が大幅に少なくなることを期待しています。
この変更の一環として、LogBox.ignoreLog
からのコンソールフィルタリングも削除します。つまり、以前にLogbox.ignoreLog
でフィルタリングしたログは、アップグレードするとコンソールに再び表示され始めます。
これは、非推奨の警告などのログが見つかり、修正されることを可能にするため、想定された動作です。
開発者エクスペリエンスの向上
React DevTools
今回のリリースでは、Webで人気の高いReact DevToolsの2つの機能をReact Nativeに導入しました。
「クリックして検査」は、React Dev Toolsの左上隅にあるオプションで、アプリ内のアイテムをクリックして、Chromeの要素インスペクタと同様にDev Toolsで検査できます。
コンポーネントのハイライトは、DevToolsで選択した要素をアプリでハイライト表示し、どのReactコンポーネントが画面上のどの要素に対応しているかを確認できるようにします。
これらが両方の機能の動作です。
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は、String
、TypedArray
、および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サポートの改善など、ユーザーがNew Architecture Working Groupで報告したいくつかのバグと問題を修正しました。
念のため、新しいアーキテクチャは、採用を容易にするために変更を繰り返すにつれて、まだ実験的なAPIエクスペリエンスです。新しいアーキテクチャドキュメントの新しい簡略化された手順を試してみて、New Architecture Working Groupにフィードバックを投稿してください。
その他の注目すべき修正
- より優れたスタックフレームの折りたたみ:React Nativeの内部フレームのリストを更新し、LogBoxが内部React Nativeフレームではなく、より頻繁にコードを表示するようにしました。これにより、問題のデバッグをより迅速に行うことができます。
- ビルド時間の改善:現在のアーキテクチャと新しいアーキテクチャの両方で、Hermesのビルド時間(iOSとAndroidの両方)を改善するために、アセットをMaven Centralに移行しました。
- Androidテンプレートの改善:Androidテンプレートが大幅に整理され、React Native Gradle Pluginに完全に依存するようになりました。テンプレート内またはWebサイトの新しい専用ページで構成手順を確認できます。
破壊的変更
- コンソールログの変更:
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)。
謝辞
このリリースは、1000件以上のコミットを追加した70人以上のコントリビューターの働きによって実現しました。
特に、これらの主要な React Native プロジェクトに貢献してくれた方々に感謝します。
- Flexbox Gap サポート: @intergalacticspacehighway および @jacobp100。
- Webに触発されたプロパティ: @gabrieldonadel @dakshbhardwaj @dhruvtailor7 @ankit-tailor @madhav23bansal。
- Codegen の改善: @AntoineDoubovetzky, @MaeIg, @Marcoo09, @Naturalclar, @Pranav-yadav, @ZihanChen-MSFT, @dakshbhardwaj, @dhruvtailor7, @gabrieldonadel, @harshsiri110, @ken0nek, @kylemacabasco, @matiassalles99, @mdaj06, @mohitcharkha, @tarunrajput, @vinayharwani13, @youedd, @byCedric。
最後に、このリリースをまとめた @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 のサポートポリシーを参照してください。