React Native 0.74 - Yoga 3.0、ブリッジレスNew Architecture、その他多数
本日、React Native 0.74をリリースしました!このリリースでは、Yoga 3.0、New Architectureの下でデフォルトのブリッジレスモード、バッチ処理されたonLayout
アップデート(New Architecture)、および新規プロジェクトのデフォルトパッケージマネージャーとしてのYarn 3を追加しました。
また、PropTypes
の削除やPushNotificationIOS
に対する破壊的変更など、非推奨APIの削除も行っています。Androidでは、サポートされる最小SDKバージョンが23(Android 6.0)になりました。
ハイライト
破壊的変更
- Android最小SDKのバンプ(Android 6.0)
- PushNotificationIOSへのAPI変更(非推奨)
- 非推奨の
PropTypes
の削除 - Flipper React Nativeプラグインの削除
- その他の破壊的変更
ハイライト
Yoga 3.0
新しいレイアウト動作
React Native 0.74には、レイアウトエンジンの最新バージョンであるYoga 3.0が含まれています。Yoga 3.0は、スタイリングをより予測可能にすることでレイアウトを改善し、Web用に記述されたコンポーネントのレンダリングをサポートします。
React Nativeは、修正によって多数の実世界のコンポーネントに影響を与えることが判明した場合、意図的にいくつかの不正確なレイアウト動作を保持し続けます。将来のバージョンのReact Nativeでは、レイアウトの適合性をより詳細に設定できるようになります。
React Nativeは、以前は、row-reverse
コンテナに設定されたmargin
、padding
、またはborder
を処理する際に、left
/right
(およびstart
/end
)のエッジを反転していました。現在、これらのプロパティの動作はWebと一致しています。以前はエッジの反転に依存していたコードは、正しくレンダリングし続けるために更新する必要がある場合があります。
スタイル | 前 | 後 |
---|---|---|
|
align-content: 'space-evenly'
のサポート
Yoga 3.0は、alignContent: 'space-evenly'
をサポートします。space-evenly
は、複数行のフレックスコンテナ内の行を、行とコンテナのエッジの間に均等に間隔を空けたギャップを使用して均等に分散します。

position: 'static'
のサポート
position: 'static'
は、New Architectureでのみサポートされています。
position: 'static'
としてマークされた要素はオフセットされず、絶対配置された要素のコンテナーブロックを決定する際に考慮されません。これにより、直接の親ではない祖先を基準にして要素を配置できます。
|
緑色の<View>
がleft
とtop
を宣言し、その親ではなく、青色の<View>
を基準に配置されていることに注意してください。
React Nativeは、position
が設定されていない場合、デフォルトでposition: 'relative'
になります。
New Architecture: デフォルトでブリッジレス
このリリースでは、New Architectureが有効になっている場合、ブリッジレスモードをデフォルトにしています。デフォルトとしてブリッジレスへの切り替えの詳細については、この投稿を参照してください。移行をスムーズにするために、ブリッジレスをカバーする相互運用レイヤーを強化し、いくつかのライブラリと連携して、初日からブリッジレスで動作するようにしました。
ブリッジレスは私たちが取り組んだ唯一の相互運用レイヤーではありません。New Renderer相互運用レイヤーも改善しました。最もエキサイティングな点は、それがデフォルトで有効になっていることです。通過する必要があるコンポーネントを指定する必要はありません!それらについてはこちらで詳しく読むことができます。
最後に、New Architectureの詳細については、react-native-new-architectureリポジトリでドキュメントを見つけることができます。New Architectureがデフォルトになると、この情報はreactnative.devに組み込まれます。
New Architecture: バッチ処理されたonLayout
アップデート
onLayout
コールバック内の状態更新がバッチ処理されるようになりました。以前は、onLayout
イベントでの各状態更新が新しいレンダリングコミットを招いていました。
function MyComponent(props) {
const [state1, setState1] = useState(false);
const [state2, setState2] = useState(false);
return (
<View>
<View
onLayout={() => {
setState1(true);
}}>
<View
onLayout={() => {
// When this event is executed, state1's new value is no longer observable here.
setState2(true);
}}>
</View>
</View>
);
}
0.74では、setState1
とsetState2
の更新がまとめてバッチ処理されます。この変更はReactの期待される動作であり、再レンダリングの回数を減らすことができます。
この変更により、バッチ処理されていない状態更新に依存していたコードが動作しなくなる可能性があります。更新関数または同等のものを使用して、このコードをリファクタリングする必要があります。
新規プロジェクト用のYarn 3
Yarn 3が、React Native Community CLIで初期化された新規プロジェクトのデフォルトのJavaScriptパッケージマネージャーになりました。
Yarn 3.xは、React Nativeライブラリとの互換性を提供するモードであるnodeLinker: node-modules
と共に使用されます。これにより、以前のデフォルトであったYarn Classic(1.x、非推奨)が置き換えられます。既存のアプリ内でYarnのバージョンをアップグレードするには、このガイドに従ってください。
$ yarn --help
━━━ Yarn Package Manager - 3.6.4 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ yarn <command>
Community CLIは、--pm
フラグを使用して他のパッケージマネージャーでプロジェクトの初期化もサポートしています(詳細はこちら)。
破壊的変更
Android最小SDKのアップグレード(Android 6.0)
React Native 0.74では、Android SDKの最小バージョン要件が23(Android 6.0)になりました。以前はAndroid 5.0(API 21)でした。この変更に関するコンテキストはこちらをご覧ください。
ボーナス:Androidアプリサイズの削減
最小SDKのアップグレードと、ネイティブビルドにおけるいくつかの改善により、ユーザーデバイス上のアプリサイズを大幅に削減することができました。
たとえば、React Native 0.74で新規作成されたアプリは、ユーザーデバイス上で約13%少ない容量を占め、デバイス上で約4MBの容量を節約できます。
非推奨のPropTypes
の削除
0.74以前、React Nativeは2017年のReact 15.5以降非推奨となっているAPIであるPropTypes
を同梱していました!現在、React Nativeからすべての組み込みPropTypes
を削除し、アプリサイズ(縮小版バンドルで26.4kB)とメモリオーバーヘッドを削減しています。
次のPropTypes
プロパティが削除されました:Image.propTypes
、Text.propTypes
、TextInput.propTypes
、ColorPropType
、EdgeInsetsPropType
、PointPropType
、ViewPropTypes
(コミットを参照)。
アプリまたはライブラリがPropTypes
に依存している場合は、TypeScriptなどの型システムへの移行を強くお勧めします。
PushNotificationIOS(非推奨)へのAPI変更
React Native 0.74では、非推奨のPushNotificationIOSライブラリを削除するためのステップを実行しています。このリリースの変更は、古いiOS APIへの参照を削除することに重点を置いています。PushNotificationIOSはAppleのUser Notificationsフレームワークに移行され、通知のスケジュールと処理のための新しいAPIを公開しています。
次のリリース(0.75)では、このライブラリを削除し、React Nativeコアからコミュニティパッケージである@react-native-community/push-notification-iosに移行する予定です。PushNotificationIOSにまだ依存している場合は、次のリリース前に移行する必要があります。
APIの変更
RCTPushNotificationManager
のdidRegisterUserNotificationSettings:
コールバックはノーオペレーションであり、削除されました。
RCTPushNotificationManager
の次のコールバックは非推奨となり、0.75で削除されます。
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
getInitialNotification()
を使用してアプリを起動した通知を取得するには、RCTPushNotificationManager
でinitialNotification
を明示的に設定する必要があります。
[RCTPushNotificationManager setInitialNotification:response.notification];
JS側では、Notification
のプロパティが変更されました。alertAction
とrepeatInterval
は非推奨となり、0.75で削除されます。
type Notification = {
...
// NEW: Seconds from now to display the notification.
fireIntervalSeconds?: ?number,
// CHANGED: Used only for scheduling notifications. Will be null when
// retrieving notifications using `getScheduledLocalNotifications` or
// `getDeliveredNotifications`.
soundName?: ?string,
// DEPRECATED: This was used for iOS's legacy UILocalNotification.
alertAction?: ?string,
// DEPRECATED: Use `fireDate` or `fireIntervalSeconds` instead.
repeatInterval?: ?string,
};
最後に、PushNotificationIOS.removeEventListener
のhandler
パラメーターは使用されておらず、削除されました。
💡移行方法
iOS
AppDelegate
でUNUserNotificationCenterDelegate
を実装する必要があります。これは、アプリの起動時にapplication:willFinishLaunchingWithOptions:
またはapplication:didFinishLaunchingWithOptions:
で行う必要があります(詳細については、Appleのドキュメントを参照)。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
通知が到着し、アプリがフォアグラウンドにある場合に呼び出されるuserNotificationCenter:willPresentNotification:withCompletionHandler:
を実装します。completionHandler
を使用して、通知がユーザーに表示されるかどうかを判断し、それに応じてRCTPushNotificationManager
に通知します。
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
// This will trigger 'notification' and 'localNotification' events on PushNotificationIOS
[RCTPushNotificationManager didReceiveNotification:notification];
// Decide if and how the notification will be shown to the user
completionHandler(UNNotificationPresentationOptionNone);
}
通知がタップされた場合の処理には、userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
を実装します。userNotificationCenter:willPresentNotification:withCompletionHandler:
でフォアグラウンド通知を表示するように設定した場合、これらのコールバックのいずれか1つでRCTPushNotificationManager
に通知する必要があります。
タップされた通知によってアプリが起動された場合は、setInitialNotification:
を呼び出します。通知がuserNotificationCenter:willPresentNotification:withCompletionHandler:
で事前に処理されていない場合は、didReceiveNotification:
も呼び出します。
- (void) userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
// This condition passes if the notification was tapped to launch the app
if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
// Allow the notification to be retrieved on the JS side using getInitialNotification()
[RCTPushNotificationManager setInitialNotification:response.notification];
}
// This will trigger 'notification' and 'localNotification' events on PushNotificationIOS
[RCTPushNotificationManager didReceiveNotification:response.notification];
completionHandler();
}
最後に、次のメソッドを削除し、代わりに呼び出される上記のコールバックにロジックを適応します。
application:didReceiveLocalNotification:
[非推奨]application:didReceiveRemoteNotification:
[非推奨]application:didReceiveRemoteNotification:fetchCompletionHandler:
[非推奨ではありませんが、UNUserNotificationCenterDelegate
メソッドによって置き換えられました]
application:didRegisterUserNotificationSettings:
とRCTPushNotificationManager
の対応するdidRegisterUserNotificationSettings:
の使用も削除します。
例:RNTesterのAppDelegate.mm
を参照してください。
JS
alertAction
への参照をすべて削除します。removeEventListener
への呼び出しのhandler
引数を削除します。repeatInterval
の使用を、代わりにfireDate
またはfireIntervalSeconds
を使用して複数の通知を発生させることで置き換えます。getScheduledLocalNotifications()
とgetDeliveredNotifications()
から返されたNotification
でsoundName
にアクセスする場合、soundName
はnullになります。
Flipper React Nativeプラグインの削除
React Nativeレイアウト、ネットワークリクエスト、およびその他のReact Nativeプラグイン機能の検査にFlipperを使用することは、現在サポートされていません。0.74では、新しいReact NativeプロジェクトからネイティブのFlipperライブラリと設定コードを削除しました。これは、依存関係の減少とより迅速なローカル設定を意味します(元のRFCを参照)。
アプリからFlipperを削除するdiffは、Upgrade Helperで見ることができます。既存のアプリでFlipperを保持する場合は、関連するdiff行を無視してください。
💡Flipperを再統合するには
Flipperは、AndroidまたはiOSアプリのデバッグのためのスタンドアロンツールとして引き続き使用でき、Flipperのドキュメントに従って手動で統合できます(Androidガイド、iOSガイド)。
Android StudioとXcodeのネイティブデバッグツールへの切り替えに投資することをお勧めします。
Flipperの代替
Flipperの機能に取って代わる、多くの専用のデバッグツールがあります。詳細については、Jamon Holmgrenによる優れた記事「React NativeアプリでFlipperが必要ない理由とその方法」をお読みください。
JavaScriptデバッグ
0.74では、Hermesデバッガーの使用が推奨されるデバッグオプションです。実験的な新しいデバッガーも試すことができます。これはExpoでもデフォルトになっています。これは早期プレビューであり、既知の問題とアップデートはこちらで確認できます。
その他の破壊的変更
一般
- スタイルにおける
start
/end
を常に書き込み方向を参照するように変更しました (#42251).
Android
FabricUIManagerProvider
からJSIModule*
を削除しました (#42059).- このAPIはオープンソースでは使用されていませんでした。代わりにTurboModulesを使用してください。
UIManagerModule.showPopupMenu
とUIManagerModule.dismissPopupMenu
を非推奨としました (#42441)- このAPIは
@react-native/popup-menu-android
npmパッケージに移行され、0.75で削除されます。
- このAPIは
iOS
- iOS codegen CLIから
configFilename
とconfigKey
引数を削除しました (#41533). bundleURL
の処理方法を変更しました (#43994).- 以前は、
bundleURL
はReact Nativeがインスタンス変数で起動されたときに設定され、更新することができませんでした。 - 現在は、
bundleUrl
は関数であり、必要に応じて再評価されるため、更新時に異なるURLを使用できます。 - この変更は、アプリの起動後に
bundleURL
変数を変更していた場合にのみアプリに影響します。この場合は、変数を更新するロジックをAppDelegate
内のbundleURL
関数に移動してください。
- 以前は、
破壊的変更の完全なリストについては、完全な変更ログを参照してください。
既知の問題
iOS
- 複数のウィンドウを使用する場合のエッジケース:メインウィンドウが非アクティブでシステムがダイアログを表示しようとすると、ダイアログが画面上の正しい位置に表示されません。#44167で修正が予定されており、0.74.1でリリースされます。
謝辞
React Native 0.74には、57人の貢献者からの1673を超えるコミットが含まれています。皆様のご尽力に感謝いたします!
このリリース後の機能のドキュメント作成に携わった追加の皆様にも感謝いたします。
- Nick Gerleman (Yoga 3.0)
- Joe Vilches (Yoga 3.0)
- Riccardo Cipolleschi (New Architecture: ブリッジレスデフォルト)
- Samuel Susla (New Architecture: バッチ処理された
onLayout
更新) - Tim Yung (非推奨の
PropTypes
の削除) - Ingrid Wang (PushNotificationIOS (非推奨)へのAPI変更)
0.74へのアップグレード
既存のプロジェクトのReact Nativeバージョン間のコード変更を確認するには、React Native Upgrade Helperとアップグレードドキュメントをご利用ください。
新規プロジェクトの作成
npx react-native@latest init MyProject
Expoを使用している場合、React Native 0.74はExpo SDK 51でサポートされます。
0.74は最新の安定版React Nativeであり、0.71.xはサポートされなくなります。詳細については、React Nativeのサポートポリシーを参照してください。5月初旬に0.71の最終的なEOLアップデートを公開する予定です。