React Native - BackHandler with Alert
up vote
1
down vote
favorite
I'm attempting to override the back button on a screen with a prompt to Logout. See the following:
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");
As you can see, on mounting change, I'm binding and unbinding "hardwareBackPress" to this.handleBackPress
. Note, I have to use .bind(this)
, otherwise I get
_this2.handleLogout is not a function
when I press the Logout in the Alert. Expected functionality is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button on previous screen has default action
But what actually happens is:
- Back button is pressed
- Navigates back
- Alert is displayed
- (Subsequent steps don't matter)
I noticed I don't have return true;
anywhere in my handleBackPress()
, so I added that:
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;
But what happens now is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button press on previous screen results in Alert being displayed
I have verified that componentDidUnmount()
is called, but it doesn't seem to have removed the event listener.
Has anyone encountered this issue before? For now, I've just resorted to globally disabling the back button by adding this handler at the entry point of the app, but that's not a long-term solution.
Edit: I noticed there's a lifecycle alternative, so I tried implementing that:
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();
And while this makes it work (somehow), it has yet another side-effect. As soon as I navigate forward (which doesn't trigger componentDidUnmount()
, due to stacked navigation), and navigate back, the back button behaves as such:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert doesn't show up
The screen I'm navigating forward to has it's back button overridden, and seems to not play well with this alternative lifecycle. Will attempt to implement different approach on all subsequent screens; see if it behaves properly then.
javascript android react-native react-navigation
add a comment |
up vote
1
down vote
favorite
I'm attempting to override the back button on a screen with a prompt to Logout. See the following:
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");
As you can see, on mounting change, I'm binding and unbinding "hardwareBackPress" to this.handleBackPress
. Note, I have to use .bind(this)
, otherwise I get
_this2.handleLogout is not a function
when I press the Logout in the Alert. Expected functionality is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button on previous screen has default action
But what actually happens is:
- Back button is pressed
- Navigates back
- Alert is displayed
- (Subsequent steps don't matter)
I noticed I don't have return true;
anywhere in my handleBackPress()
, so I added that:
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;
But what happens now is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button press on previous screen results in Alert being displayed
I have verified that componentDidUnmount()
is called, but it doesn't seem to have removed the event listener.
Has anyone encountered this issue before? For now, I've just resorted to globally disabling the back button by adding this handler at the entry point of the app, but that's not a long-term solution.
Edit: I noticed there's a lifecycle alternative, so I tried implementing that:
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();
And while this makes it work (somehow), it has yet another side-effect. As soon as I navigate forward (which doesn't trigger componentDidUnmount()
, due to stacked navigation), and navigate back, the back button behaves as such:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert doesn't show up
The screen I'm navigating forward to has it's back button overridden, and seems to not play well with this alternative lifecycle. Will attempt to implement different approach on all subsequent screens; see if it behaves properly then.
javascript android react-native react-navigation
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm attempting to override the back button on a screen with a prompt to Logout. See the following:
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");
As you can see, on mounting change, I'm binding and unbinding "hardwareBackPress" to this.handleBackPress
. Note, I have to use .bind(this)
, otherwise I get
_this2.handleLogout is not a function
when I press the Logout in the Alert. Expected functionality is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button on previous screen has default action
But what actually happens is:
- Back button is pressed
- Navigates back
- Alert is displayed
- (Subsequent steps don't matter)
I noticed I don't have return true;
anywhere in my handleBackPress()
, so I added that:
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;
But what happens now is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button press on previous screen results in Alert being displayed
I have verified that componentDidUnmount()
is called, but it doesn't seem to have removed the event listener.
Has anyone encountered this issue before? For now, I've just resorted to globally disabling the back button by adding this handler at the entry point of the app, but that's not a long-term solution.
Edit: I noticed there's a lifecycle alternative, so I tried implementing that:
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();
And while this makes it work (somehow), it has yet another side-effect. As soon as I navigate forward (which doesn't trigger componentDidUnmount()
, due to stacked navigation), and navigate back, the back button behaves as such:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert doesn't show up
The screen I'm navigating forward to has it's back button overridden, and seems to not play well with this alternative lifecycle. Will attempt to implement different approach on all subsequent screens; see if it behaves properly then.
javascript android react-native react-navigation
I'm attempting to override the back button on a screen with a prompt to Logout. See the following:
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");
As you can see, on mounting change, I'm binding and unbinding "hardwareBackPress" to this.handleBackPress
. Note, I have to use .bind(this)
, otherwise I get
_this2.handleLogout is not a function
when I press the Logout in the Alert. Expected functionality is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button on previous screen has default action
But what actually happens is:
- Back button is pressed
- Navigates back
- Alert is displayed
- (Subsequent steps don't matter)
I noticed I don't have return true;
anywhere in my handleBackPress()
, so I added that:
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;
But what happens now is:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert is displayed
- Ok is pressed
- Navigates back
- Back button press on previous screen results in Alert being displayed
I have verified that componentDidUnmount()
is called, but it doesn't seem to have removed the event listener.
Has anyone encountered this issue before? For now, I've just resorted to globally disabling the back button by adding this handler at the entry point of the app, but that's not a long-term solution.
Edit: I noticed there's a lifecycle alternative, so I tried implementing that:
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();
And while this makes it work (somehow), it has yet another side-effect. As soon as I navigate forward (which doesn't trigger componentDidUnmount()
, due to stacked navigation), and navigate back, the back button behaves as such:
- Back button is pressed
- Functionality disabled (doesn't navigate)
- Alert doesn't show up
The screen I'm navigating forward to has it's back button overridden, and seems to not play well with this alternative lifecycle. Will attempt to implement different approach on all subsequent screens; see if it behaves properly then.
javascript android react-native react-navigation
javascript android react-native react-navigation
edited Nov 9 at 20:14
asked Nov 9 at 20:05
Tim Lewis
10.2k63358
10.2k63358
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
Using the lifecycle alternative from the Documentation (https://facebook.github.io/react-native/docs/backhandler) seems to handle odd behaviour with Alert and 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");
As long as all subsequent screens that need the back button overridden also use the same logic:
Detail.js
(subsequent screen in Stack navigator):
componentDidMount()
this.backHandler = BackHandler.addEventListener("hardwareBackPress", () =>
return this.props.navigation.navigate("Dashboard");
);
componentWillUnmount()
this.backHandler.remove();
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
Using the lifecycle alternative from the Documentation (https://facebook.github.io/react-native/docs/backhandler) seems to handle odd behaviour with Alert and 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");
As long as all subsequent screens that need the back button overridden also use the same logic:
Detail.js
(subsequent screen in Stack navigator):
componentDidMount()
this.backHandler = BackHandler.addEventListener("hardwareBackPress", () =>
return this.props.navigation.navigate("Dashboard");
);
componentWillUnmount()
this.backHandler.remove();
add a comment |
up vote
0
down vote
accepted
Using the lifecycle alternative from the Documentation (https://facebook.github.io/react-native/docs/backhandler) seems to handle odd behaviour with Alert and 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");
As long as all subsequent screens that need the back button overridden also use the same logic:
Detail.js
(subsequent screen in Stack navigator):
componentDidMount()
this.backHandler = BackHandler.addEventListener("hardwareBackPress", () =>
return this.props.navigation.navigate("Dashboard");
);
componentWillUnmount()
this.backHandler.remove();
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
Using the lifecycle alternative from the Documentation (https://facebook.github.io/react-native/docs/backhandler) seems to handle odd behaviour with Alert and 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");
As long as all subsequent screens that need the back button overridden also use the same logic:
Detail.js
(subsequent screen in Stack navigator):
componentDidMount()
this.backHandler = BackHandler.addEventListener("hardwareBackPress", () =>
return this.props.navigation.navigate("Dashboard");
);
componentWillUnmount()
this.backHandler.remove();
Using the lifecycle alternative from the Documentation (https://facebook.github.io/react-native/docs/backhandler) seems to handle odd behaviour with Alert and 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");
As long as all subsequent screens that need the back button overridden also use the same logic:
Detail.js
(subsequent screen in Stack navigator):
componentDidMount()
this.backHandler = BackHandler.addEventListener("hardwareBackPress", () =>
return this.props.navigation.navigate("Dashboard");
);
componentWillUnmount()
this.backHandler.remove();
answered Nov 9 at 20:19
Tim Lewis
10.2k63358
10.2k63358
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53232614%2freact-native-backhandler-with-alert%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown