はじめに
タイトルままです。
ReactNativeで通知からアプリを開いたときに、
通知の種類に合わせて任意の画面を表示する方法について紹介します。
説明しないこと
- react-navigationの基本的な使い方
- react-native-push-notificationの基本的な使い方
使用ライブラリ
- 通知用
@react-native-community/push-notification-ios:^1.8.0
react-native-push-notification:^7.4.0
- タブ用
@react-navigation/native:^5.9.4
react-native-reanimated:^2.2.0
react-native-gesture-handler:^1.10.3
react-native-screens:^3.4.0
react-native-safe-area-context:^3.2.0
@react-native-community/masked-view:^0.1.11
@react-navigation/bottom-tabs:^5.11.11
コード
import React, {createRef} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import PushNotification from 'react-native-push-notification';
const navigation = createRef().current;
PushNotification.configure({
onNotification: notification => {
navigation.navigate(notification.data.screen);
},
});
PushNotification.popInitialNotification(initialNotification => {
if (initialNotification) {
navigation.navigate(initialNotification.data.screen);
}
});
const scheduleNotification = (screenName) => {
PushNotification.localNotificationSchedule({
id: 1,
title: 'title',
message: 'message',
date: new Date(now.setMinutes(now.getMinutes() + 1)), // 1分後
userInfo: {
screen: screenName,
},
channelId: 'CHANNEL_ID',
});
}
...
<NavigationContainer ref={navigationRef}>
<Tab.Navigator initialRouteName="Home">
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Tab1" component={Tab1Screen} />
<Tab.Screen name="Tab2" component={Tab2Screen} />
<Tab.Screen name="Tab3" component={Tab3Screen} />
<Tab.Screen name="Tab4" component={Tab4Screen} />
</Tab.Navigator>
</NavigationContainer>
解説
const navigationRef = createRef();
...
<NavigationContainer ref={navigationRef}>
<Tab.Navigator initialRouteName="Home">
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Tab1" component={Tab1Screen} />
...
</Tab.Navigator>
</NavigationContainer>
通知からアプリを開いたときの処理は、
後述のPushNotification.configure
で設定するのですが、
react-native-push-notificationのドキュメントでは、
Must be outside of any component LifeCycle (such as `componentDidMount`).
とあり、
Reactのライフサイクルの影響で重複して設定されることがないよう、
Reactコンポーネント外で実行する必要があります。
そのため、必然的にreact-navigation
の画面遷移はコンポーネント外で行うことになり、
スクリーンに渡ってくるprops
やuseNavigation
を使えません。
そこで、NavigationContainer
にRefを渡して、navigationにアクセスする方法を取ります。
PushNotification.configure({
onNotification: notification => {
navigation.navigate(notification.data.screen);
},
});
PushNotification.configure
のonNotification
では、
アプリを開いている状態、もしくはアプリがバックグラウンドで起動している状態で
通知をタップした場合の設定を行うことができます。
コールバック引数のnotification
のdata
には、
通知設定のuserInfo
パラメータに設定したデータが渡ってきます。
遷移先がReactのstate
に依存するような場合には、
通知設定時に遷移先を設定することで、通知の種類に応じた画面を表示することができます。
const scheduleNotification = (screenName) => {
PushNotification.localNotificationSchedule({
id: 1,
title: 'title',
message: 'message',
date: new Date(now.setMinutes(now.getMinutes() + 1)), // 1分後
userInfo: {
screen: screenName,
},
channelId: 'CHANNEL_ID',
});
}
アプリが起動している状態(バックグラウンド含む)では、
PushNotification.configure
で通知をタップしたときの挙動を設定できますが、
アプリが起動していない状態では、
PushNotification.popInitialNotification
を使用することで、
通知からアプリを開いたときの挙動を設定できます。
PushNotification.popInitialNotification(initialNotification => {
if (initialNotification) {
navigation.navigate(initialNotification.data.screen);
}
});
initialNotification
にはPushNotification.configure
のonNotification
と同じく、
userInfo
で渡したパラメータがdata
に渡ってきます。
参考