本日、React Native 0.74をリリースします!このリリースでは、Yoga 3.0、New ArchitectureでのBridgelessのデフォルト化、バッチ化されたonLayoutアップデート(New Architecture)、新規プロジェクトのデフォルトパッケージマネージャーとしてのYarn 3が追加されました。また、非推奨APIの削除も行っており、PropTypesの削除とPushNotificationIOSの破壊的変更が含まれます。Androidでは、SDK 23(Android 6.0)が最小サポートバージョンになりました。
ハイライト
- Yoga 3.0
- New Architecture: Bridgelessがデフォルト
- New Architecture: バッチ化されたonLayoutアップデート
- 新規プロジェクトでのYarn 3
破壊的変更
- Android最小SDK引き上げ(Android 6.0)
- PushNotificationIOS(非推奨)のAPI変更
- 非推奨PropTypesの削除
- Flipper React Native Pluginの削除
- その他の破壊的変更
ハイライト
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と一致しています。以前にエッジが反転されることに依存していたコードは、正しくレンダリングを続けるために更新が必要な場合があります。
| スタイル | 以前 | 以後 |
|---|
View style={{flexDirection: 'row', backgroundColor: 'red', margin: 10, width: 200, height: 100}}><View style={{flexDirection: 'row-reverse', backgroundColor: 'blue', flex: 1, marginLeft: 50}}><View style={{backgroundColor: 'green', height: '50%', flex: 1, marginLeft: 50}} /></View></View> | | |
align-content: 'space-evenly'のサポート
Yoga 3.0ではalignContent: 'space-evenly'のサポートが追加されました。space-evenlyは、複数行のflexコンテナ内の行を、行とコンテナエッジの間に配置された均等な間隔のギャップを使用して分散します。
出典: World Wide Web Consortium
position: 'static'のサポート
情報
position: 'static'はNew Architectureでのみサポートされています。
position: 'static'とマークされた要素はオフセットできず、絶対配置された要素の包含ブロックを決定する際に考慮されません。これにより、直接の親ではない祖先に対して要素を相対的に配置できます。
<View style={{backgroundColor: 'blue', width: 200, height: 200, flexDirection: 'row-reverse'}}>
<View style={{backgroundColor: 'red', width: 100, height: 100, position: 'static'}}>
<View style={{backgroundColor: 'green', width: 25, height: '25%', left: 25, top: 25, position: 'absolute'}} />
</View>
</View>
緑の要素がleftとtopを宣言し、その親ではなく青に対して配置されていることに注目してください。React Nativeは、positionが設定されていない場合、引き続きposition: 'relative'をデフォルトとします。
New Architecture: Bridgelessがデフォルト
このリリースでは、New Architectureが有効な場合にBridgeless Modeをデフォルトにしています。Bridgelessをデフォルトに切り替えることについて詳しくは、この投稿をご覧ください。
移行をスムーズにするため、BridgelessをカバーするためのInteropレイヤーを強化し、複数のライブラリと協力して、初日からBridgelessで動作することを確認しました。
Bridgelessは私たちが取り組んだ唯一のInteropレイヤーではありません。New Renderer Interopレイヤーも改善しました。最もエキサイティングな点は、これがデフォルトで有効になったことです。通過する必要があるコンポーネントを指定する必要がありません!詳細についてはこちらをご覧ください。
最後に、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={() => {
// このイベントが実行されるとき、state1の新しい値はここでは観測できません。
setState2(true);
}}>
</View>
</View>
</View>
);
}
0.74では、setState1とsetState2の更新が一緒にバッチ化されます。この変更はReactでの期待される動作であり、再レンダリングを減らすことができます。
危険
この変更により、バッチ化されていない状態更新に依存していたコードが壊れる可能性があります。このようなコードは、updater関数または同等のものを使用するようにリファクタリングする必要があります。
新規プロジェクトでのYarn 3
Yarn 3が、React Native Community CLIで初期化された新規プロジェクトのデフォルトJavaScriptパッケージマネージャーになりました。Yarn 3.xはnodeLinker: node-modulesモードで使用され、React Nativeライブラリとの互換性を提供します。これは、以前のデフォルトであった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 = {
...
fireIntervalSeconds?: ?number,
soundName?: ?string,
alertAction?: ?string,
repeatInterval?: ?string,
};
最後に、PushNotificationIOS.removeEventListenerのhandlerパラメータは使用されないため削除されました。
💡 iOSの移行方法
AppDelegateでUNUserNotificationCenterDelegateを実装する必要があります。これはapplication:willFinishLaunchingWithOptions:またはapplication:didFinishLaunchingWithOptions:でアプリ起動時に行う必要があります(詳細はApple Docsを参照)。
- (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 {
[RCTPushNotificationManager didReceiveNotification:notification];
completionHandler(UNNotificationPresentationOptionNone);
}
通知がタップされたときを処理するには、userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:を実装します。userNotificationCenter:willPresentNotification:withCompletionHandler:でフォアグラウンド通知を表示するように設定した場合は、これらのコールバックのいずれかでのみRCTPushNotificationManagerに通知する必要があります。
タップされた通知がアプリの起動につながった場合は、setInitialNotification:を呼び出します。通知が以前にuserNotificationCenter:willPresentNotification:withCompletionHandler:で処理されていない場合は、didReceiveNotification:も呼び出します:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
[RCTPushNotificationManager setInitialNotification:response.notification];
}
[RCTPushNotificationManager didReceiveNotification:response.notification];
completionHandler();
}
最後に、以下のメソッドを削除し、代わりに呼び出される上記のコールバックにロジックを適応させます:
application:didReceiveLocalNotification: [非推奨]
application:didReceiveRemoteNotification: [非推奨]
application:didReceiveRemoteNotification:fetchCompletionHandler: [非推奨ではありませんが、UNUserNotificationCenterDelegateメソッドに置き換えられます]
application:didRegisterUserNotificationSettings:とRCTPushNotificationManagerの対応するdidRegisterUserNotificationSettings:の使用も削除してください。
例:RNTester AppDelegate.mmを参照してください。
JS
alertActionへの参照をすべて削除してください。
removeEventListenerの呼び出しでhandler引数を削除してください。