React Native: Android の ハードウェアバックボタン で前の画面に戻れないように制御する

バージョン

  • react-native: 0.57.8
  • react-navigation: 2.11.2

ドキュメント

概要

  • 遷移上、前の画面へ戻れないようにしたい、という場合、下記の制御が必要

    1. スワイプバック できないようにする (iOS/Android)
    2. ハードウェアバックボタン で戻れないようにする (Android)
  • 今回は、 2.ハードウェアバックボタンで戻れないようにする の方法についてメモする

ハードウェアバックボタンで戻れないようにする方法

サンプル

import {BackHandler} from "react-native";

export default class TestScreen extends React.Component<Props, State> {
  private backHandler = null;

  componentDidMount() {
    if (isAndroid) {
      if (this.backHandler) {
        this.backHandler.remove()
      }
      // ハードウェアバックボタンで前の画面に戻れなくする
      this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => true);
    }
  }

  componentWillUnmount() {
    if (isAndroid) {
      if (isAndroid && this.backHandler) {
        this.backHandler.remove()
      }
    }
  }

ただし、これだと、BackHandler.addEventListener した画面をアンマウントする際に制御を解除するので、
画面がマウントされている間は他の画面でもハードウェアバックできなくなってしまった。

そこで、下記のようにして、BackHandler.addEventListener した画面がフォーカスされている場合のみハードウェアバックを制御するようにした。

import {BackHandler} from "react-native";

export default class TestScreen extends React.Component<Props, State> {
  private backHandler = null;

  componentDidMount() {
    if (isAndroid) {
      if (this.backHandler) {
        this.backHandler.remove()
      }
      this.backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
        // TestScreen がフォーカスされている場合のみ、ハードウェアバック不可にする
        if (this.props.navigation.isFocused()) {
          return true;
        }
        return false;         
      });
    }
  }

  componentWillUnmount() {
    if (isAndroid) {
      if (isAndroid && this.backHandler) {
        this.backHandler.remove()
      }
    }
  }

もっとスマートな方法があればご教示頂けると嬉しいです。