カスタム Android バックボタンの挙動
デフォルトでは、ユーザーが Android のハードウェアバックボタンを押すと、react-navigation は画面をポップするか、ポップする画面がない場合はアプリを終了します。これは賢明なデフォルトの動作ですが、カスタム処理を実装したい状況もあるでしょう。
例として、ユーザーがリストでアイテムを選択している画面と、「選択モード」がアクティブになっている場合を考えてみましょう。バックボタンを押すと、まず「選択モード」を非アクティブ化し、2回目のバックボタンを押したときのみ画面をポップする必要があります。次のコードスニペットは、この状況を示しています。react-native に付属の BackHandler
と、カスタムの hardwareBackPress
リスナーを追加するための useFocusEffect
フックを利用しています。
onBackPress
から true
を返すと、イベントが処理されたことを示し、react-navigation のリスナーは呼び出されず、画面はポップしません。false
を返すと、イベントがバブルアップし、react-navigation のリスナーが画面をポップします。
function ScreenWithCustomBackBehavior() {
// ...
useFocusEffect(
React.useCallback(() => {
const onBackPress = () => {
if (isSelectionModeEnabled()) {
disableSelectionMode();
return true;
} else {
return false;
}
};
const subscription = BackHandler.addEventListener(
'hardwareBackPress',
onBackPress
);
return () => subscription.remove();
}, [isSelectionModeEnabled, disableSelectionMode])
);
// ...
}
提示されたアプローチは、StackNavigator
に表示される画面でうまく機能します。他の状況でのカスタムバックボタン処理は、現時点ではサポートされていない場合があります(例:これが機能しない既知のケースは、開いているドロワーでバックボタンの押下を処理したい場合です。このようなユースケースのプルリクエストを歓迎します!)。
システムバックボタンをオーバーライドするのではなく、画面から戻るのを防ぎたい場合は、戻る操作の防止のドキュメントを参照してください。
なぜコンポーネントのライフサイクルメソッドを使用しないのか
最初は、componentDidMount
を使用してバックプレスイベントをサブスクライブし、componentWillUnmount
を使用してサブスクライブを解除するか、useEffect
を使用してリスナーを追加することを考えるかもしれません。このアプローチは機能しません - 詳細については、ナビゲーションのライフサイクルをご覧ください。