React Native - BackHandler с оповещением

1

Я пытаюсь переопределить кнопку "Назад" на экране, предлагая выйти из системы. Смотрите следующее:

import React, { Component } from "react";
import { Alert, BackHandler } from "react-native";

export default class Dashboard extends Component {

    constructor(props) {
        super(props);
    }

    componentDidMount() {

        BackHandler.addEventListener("hardwareBackPress",this.handleBackPress);
    }

    componentWillUnmount() {
        BackHandler.removeEventListener("hardwareBackPress", this.handleBackPress);
    }

    handleBackPress() {
        Alert.alert(
            "Logout",
            "Are you sure you want to logout?",
            [
                {
                    text: "Cancel",
                    onPress: () => {
                        console.log("Cancel Pressed");
                    },
                    style: "cancel"
                },
                { text: "Logout", onPress: () => this.handleLogout() }
            ],
            { cancelable: false }
        );
    }

    handleLogout() {
        this.props.navigation.navigate("Login");
    }
}

Как вы можете видеть, при изменении монтирования я привязываю и освобождаю "hardwareBackPress" к this.handleBackPress. Обратите внимание, я должен использовать .bind(this), в противном случае я получаю

_this2.handleLogout не является функцией

когда я нажимаю Выход из системы в оповещении. Ожидаемая функциональность:

  • Кнопка Назад нажата
  • Функциональность отключена (не перемещается)
  • Оповещение отображается
  • Хорошо нажата
  • Навигация назад
  • Кнопка Назад на предыдущем экране имеет действие по умолчанию

Но на самом деле происходит следующее:

  • Кнопка Назад нажата
  • Навигация назад
  • Оповещение отображается
  • (Последующие шаги не имеют значения)

Я заметил, что у меня нет return true; в любом месте моего handleBackPress(), поэтому я добавил, что:

handleBackPress() {
    Alert.alert(
        "Logout",
        "Are you sure you want to logout?",
        [
            {
                text: "Cancel",
                onPress: () => {
                    console.log("Cancel Pressed");
                },
                style: "cancel"
            },
            {
                text: "Logout",
                onPress: () => {
                    return this.handleLogout();
                }
            }
        ],
        { cancelable: false }
    );

    return true;
}

Но что происходит сейчас:

  • Кнопка Назад нажата
  • Функциональность отключена (не перемещается)
  • Оповещение отображается
  • Хорошо нажата
  • Навигация назад
  • При нажатии кнопки "Назад" на предыдущем экране отображается предупреждение

Я проверил, что вызвана componentDidUnmount(), но, похоже, он не удалил прослушиватель событий.

Кто-нибудь сталкивался с этой проблемой раньше? Сейчас я только что прибег к глобальному отключению кнопки "Назад", добавив этот обработчик в точке входа приложения, но это не долгосрочное решение.

Редактировать: я заметил альтернативу жизненного цикла, поэтому я попытался реализовать это:

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        Alert.alert("Logout", "Are you sure you want to logout?", [{ text: "Cancel", onPress: () => {}, style: "cancel" }, { text: "Logout", onPress: () => this.handleLogout() }], { cancelable: false });
        return true;
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}

И хотя это заставляет его работать (как-то), у него есть еще один побочный эффект. Как только я перемещаюсь вперед (который не вызывает componentDidUnmount(), из-за сложенной навигации), и возвращаюсь назад, кнопка "Назад" ведет себя так:

  • Кнопка Назад нажата
  • Функциональность отключена (не перемещается)
  • Оповещение не появляется

Экран, к которому я перехожу, переопределяет кнопку "Назад", и, похоже, не подходит для этого альтернативного жизненного цикла. Попытка реализовать другой подход на всех последующих экранах; посмотрим, будет ли он вести себя правильно тогда.

Теги:
react-native
react-navigation

1 ответ

0
Лучший ответ

Использование альтернативы жизненного цикла из документации (https://facebook.github.io/react-native/docs/backhandler), кажется, обрабатывает странное поведение с Alert и return true; :

Dashboard.js

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        Alert.alert("Logout", "Are you sure you want to logout?", [{ text: "Cancel", onPress: () => {}, style: "cancel" }, { text: "Logout", onPress: () => this.handleLogout() }], { cancelable: false });
        return true;
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}

handleLogout() {
    global.screenName = "Dashboard";
    return this.props.navigation.navigate("Login");
}

Пока все последующие экраны, которым необходимо переопределить кнопку возврата, также используют ту же логику:

Detail.js (следующий экран в навигаторе стека):

componentDidMount() {
    this.backHandler = BackHandler.addEventListener("hardwareBackPress", () => {
        return this.props.navigation.navigate("Dashboard");
    });
}

componentWillUnmount() {
    this.backHandler.remove();
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню