Reputation: 2516
I have enabled backandroid to show logout alert in home screen. Problem is even though screen navigated away from home screen. still Logout alert coming. basic back navigation is also disabled.
HomeScreen.js
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this._handleback);
}
componentWillUnmount() {
//Forgetting to remove the listener will cause pop executes multiple times
BackHandler.removeEventListener('hardwareBackPress', this._handleback);
}
_handleback = () => {
Alert.alert(i18N.t('alertHeader'), i18N.t('logoutqHeader'), [
{
text: i18N.t('yes'), onPress: () => { this.props.navigation.navigate('login'); }
},
{ text: i18N.t('cancel'), onPress: () => { return true; }, style: 'cancel' },
], { cancelable: false });
return true;
};
I want to show logout alert only in home screen. In other screens I want to follow basic back navigation. Please let me know how to solve this.
Upvotes: 2
Views: 3746
Reputation: 809
Approach #1
import { BackHandler } from 'react-native';
constructor(props) {
super(props)
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
handleBackButtonClick() {
this.props.navigation.goBack(null);
return true;
}
But this has an issue, i.e, componentWillMount
lifecycle method in React has been deprecated since React version 16.3.0
Hence, Approach #2
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
handleBackButtonClick() {
if(this.props.route.name === "login"){
this.props.navigation.navigate("App Intro");
return true;
}
else{
this.props.navigation.goBack(null);
return true;
}
}
async componentDidMount(){
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
Upvotes: 0
Reputation: 11
backHandler
is applying to all your screen, it's because of using useEffect
hook. Let me share my code where I had used useFocusEffect
and useCallback
method this works fine for me.
useFocusEffect(
React.useCallback(() => {
const onBackPress = () => {
Alert.alert('Hold on!', 'Are you sure you want to go back?', [
{
text: 'Cancel',
onPress: () => null,
style: 'cancel',
},
{text: 'YES', onPress: () => navigation.goBack()},
]);
return true;
};
BackHandler.addEventListener('hardwareBackPress', onBackPress);
return () =>
BackHandler.removeEventListener('hardwareBackPress', onBackPress);
}, []),
);
Upvotes: 1
Reputation: 75
Here is an example implementation:
componentDidMount() {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBack);
}
componentWillUnmount() {
this.backHandler.remove();
}
Upvotes: 0
Reputation: 11
I just added clean up action in useEffect hook and it worked fine for me
useEffect(() => {
BackHandler.addEventListener("hardwareBackPress", handleBackButton);
return () => {
BackHandler.removeEventListener("hardwareBackPress", handleBackButton);
};
}, [])
Upvotes: 1
Reputation: 2516
Following approach helped me to solve it.
In Homescreen I have included alert normally like in the question.
For the rest of the screens I have included goback() of navigation.
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', () => this.props.navigation.goBack());
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', () => this.props.navigation.goBack());
}
It achieved my requirement of showing alert in home screen and going back in other screens with this approach.
Upvotes: 1
Reputation: 3687
One solution can be to check for the current screen . in _handleclick add a check for routeName. There can be more solutions, but its difficult to tell by seeing only this amount of code
_handleback = () => {
//instead of home screen, add your routeName when you are on home screen
if(this.props.navigation.state.routeName === "homeScreen")
Alert.alert(i18N.t('alertHeader'), i18N.t('logoutqHeader'), [
{
text: i18N.t('yes'), onPress: () => { this.props.navigation.navigate('login'); }
},
{ text: i18N.t('cancel'), onPress: () => { return true; }, style: 'cancel' },
], { cancelable: false });
return true;
}
};
Upvotes: 0