React Native 0.71: デフォルトでTypeScript、Flexbox Gapなど…
本日、React Native バージョン 0.71をリリースします!これは機能満載のリリースで、以下が含まれます。
- TypeScriptのデフォルト化
- Flexbox Gapによるレイアウトの簡素化
- アクセシビリティ、スタイル、イベントのためのWebに着想を得たprops
- PropTypesの復活
- 開発者体験の向上
- New Architectureのアップデート
この記事では、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 にインスパイアされたプロップ
このリリースには、React Native の API を多くのプラットフォーム間で整合させるために、Web 標準にインスパイアされた多くの新しいプロップが含まれています。これらの新しいプロップは純粋に追加的なものであるため、同等のアクセシビリティ、動作、またはスタイルプロップについて、移行や動作変更は予想されません。
導入された新しいプロップエイリアスについては、異なる名前の既存のプロップがあり、両方が指定されている場合、新しいエイリアスプロップ値が優先されます。たとえば、このリリースでは、Image コンポーネントの `source` に `src` プロップエイリアスが追加され、Web の `src` プロップと整合しています。`src` と `source` の両方が提供された場合、新しい `src` プロップが使用されます。
アクセシビリティ
既存の 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 を参照してください。
コンポーネント固有の動作
コアコンポーネントのプロップ名を同等の 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` の以下のハンドラーがホバーをサポートします。
- `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 のプロップタイプ、たとえば `ViewPropTypes` や `Text.propTypes` は 0.66 で非推奨となり、それらにアクセスすると非推奨警告が出力されていました。0.68 で削除された際、多くの開発者が最新バージョンの React Native にアップグレードする際にエラーを経験し始めました。
調査の結果、いくつかの問題がコミュニティが非推奨警告に対して行動を起こすのを妨げていたことが判明しました。第一に、非推奨警告が常に実行可能であるとは限らず、人々がそれを無視する原因となっていました(issue 1、issue 2)。第二に、非推奨警告は `LogBox.ignoreLogs` によって誤ってフィルタリングされていました。これら両方は修正されましたが、非推奨の呼び出しサイトをアップグレードするための時間をさらに確保したいと考えています。
そのため、このリリースでは React Native のプロップタイプを再度追加し、人々がそれらを使用しないようにコードをアップグレードおよび移行しやすくしています。`deprecated-react-native-prop-types` パッケージも 0.71 のすべてのプロップ用に更新されました。将来的には、非推奨化を進め、プロップタイプを再度削除する予定です。削除を再検討する際には、コミュニティが経験する問題が大幅に減少すると予想しています。
この変更の一環として、`LogBox.ignoreLog` からコンソールフィルターも削除しています。これは、以前 `Logbox.ignoreLog` でフィルターしていたログがアップグレード時にコンソールに再び表示され始めることを意味します。
これは、非推奨警告などのログが検出され、修正されることを可能にするため、想定内の動作です。
開発者エクスペリエンスの向上
React DevTools
このリリースでは、Web の人気のある React DevTools 機能の 2 つを React Native に導入しました。
"クリックして検査" は、React DevTools の左上隅にあるオプションで、Chrome の要素インスペクターと同様に、アプリ内のアイテムをクリックして DevTools で検査できます。
コンポーネントのハイライトは、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 サポートなど)を修正しました。
繰り返しになりますが、新しいアーキテクチャは、導入を容易にするための変更を反復しているため、まだ実験的な API エクスペリエンスです。新しいアーキテクチャドキュメントの新しい簡素化された手順を試して、フィードバックを新しいアーキテクチャワーキンググループに投稿してください。
その他の注目すべき修正
- スタックフレームの折りたたみ改善: React Native の内部フレームのリストを更新しました。これにより、LogBox が内部の React Native フレームではなく、あなたのコードをより頻繁に表示するようになり、問題のデバッグが高速化されます。
- ビルド時間の改善: Hermes の現在のアーキテクチャと新しいアーキテクチャの両方で、プレハブのアセットを Maven Central に移行し、ビルド時間(iOS および Android の両方)を改善しました。
- Android テンプレートの改善: Android テンプレートが大幅に整理され、完全に React Native Gradle Plugin に依存するようになりました。設定手順はテンプレート内またはウェブサイトの新しい専用ページで直接見つけることができます。
破壊的変更
- コンソールログの変更: `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プロジェクトに貢献してくださった方々に感謝したいと思います。
- Flexbox Gap Support: @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 のサポートポリシーを参照してください。