Я пытаюсь переопределить кнопку "Назад" на экране, предлагая выйти из системы. Смотрите следующее:
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()
, из-за сложенной навигации), и возвращаюсь назад, кнопка "Назад" ведет себя так:
Экран, к которому я перехожу, переопределяет кнопку "Назад", и, похоже, не подходит для этого альтернативного жизненного цикла. Попытка реализовать другой подход на всех последующих экранах; посмотрим, будет ли он вести себя правильно тогда.
Использование альтернативы жизненного цикла из документации (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();
}