Reputation: 7625
I am facing this weired issue with android back button handler. Consider I have 3 screens, A, B, and C. I am using stack navigator. A navigates to B, which navigates to C.
I want to be able to go back from C to B, but not from B to A. For this, in B, I do this:
async componentDidMount() {
if (Platform.OS === "android") {
BackHandler.addEventListener(
"hardwareBackPress",
this.onBackButtonPressAndroid.bind(this)
);
}
}
onBackButtonPressAndroid = () => {
Alert.alert("Backed"); //this is just to test
return true; //make it true to prevent going back
};
And in C:
if (Platform.OS === "android") {
BackHandler.addEventListener(
"hardwareBackPress",
this.onBackButtonPressAndroid.bind(this)
);
}
onBackButtonPressAndroid = () => {
this.props.navigation.goBack(null);
return true;
};
I have removed the event listener in componentWillUnmount
.
When I go from A to B, and press back button, it behaves correctly: it does not go back to A, and I see the alert.
But then when I go from B to C, then combe back to B (using back button), if I again press back button, it goes back to A and I don't see the alert.
Why is that happening?
Update If I don not set the event handler in C, then when I press back button, I see the alert! that means the handlers in B gets called!
Upvotes: 0
Views: 885
Reputation: 2574
Add/remove the event listener based on the navigation lifecycle, rather than the component lifecycle. The event listener should not be necessary in C.
import React from 'react'
import { Alert, Platform } from 'react-native'
import { NavigationEvents } from 'react-navigation'
export default class YourComponent extends React.Component {
onBackPressAndroid = () => {
Alert.alert('Cannot go back')
return true
}
didFocus = () => BackHandler.addEventListener(
'hardwareBackPress',
this._onBackPressAndroid
)
willBlur = () => BackHandler.removeEventListener(
'hardwareBackPress',
this._onBackPressAndroid
)
render() {
<>
{ Platform.OS === 'android'
<NavigationEvents
onDidFocus={this.didFocus}
onWillBlur={this.willBlur}
/>
}
{ /* your component render */ }
</>
}
}
Upvotes: 2