Reputation: 441
I am new to react-native. I have two screens screen A
and screen B
. I register BackHandler event listener in screen A
and want to remove the listener on screen B
. How can I do it.
I tried the following code.
class ScreenA extends React.Component{
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
handleBackPress = () => {
return true;
}
_navigateToB = () => {
this.props.navigation.navigate('ScreenB')
}
render(){
return <View><Botton onPress={ () => { this._navigateToB } } /></View>
}
}
// second screen
class ScreenB extends React.Component{
componentDidMount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress )
//BackHandler.removeEventListener('hardwareBackPress', () => true ) //I tried it too
//BackHandler.removeEventListener('hardwareBackPress', true ) //I tried it too
}
handleBackPress = () => {
return true;
}
}
But this code is not removing the backHandle event listener.
and when I put the BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress )
in _navigateToB
of screen A
then it is working fine. Can I remove this listener on the screen B
Upvotes: 2
Views: 3203
Reputation: 3620
firstly, in component B you don't register the BackHandler, so when you remove it, it reports the error.
Secondly, when you put it in the _navigateToB of screen A, you register it in the component A componentDidMount method before, so you can remove it.
you can not remove it on a different screen.
if you want to know more, we can see it source code:
const _backPressSubscriptions = [];
addEventListener: function(
eventName: BackPressEventName,
handler: Function,
): {remove: () => void, ...} {
if (_backPressSubscriptions.indexOf(handler) === -1) {
_backPressSubscriptions.push(handler);
}
return {
remove: (): void => BackHandler.removeEventListener(eventName, handler),
};
},
it put the handler function in a array; and it is not global. so you only can add and remove in the same component.
then in the android native, when it receive the hardware back event, it will send it to the react native js.
// located in the DeviceEventManagerModule
/** Sends an event to the JS instance that the hardware back has been pressed. */
public void emitHardwareBackPressed() {
getReactApplicationContext()
.getJSModule(RCTDeviceEventEmitter.class)
.emit("hardwareBackPress", null);
}
in the react native BackHandler.js source code, we can it add this event use RCTDeviceEventEmitter.
const DEVICE_BACK_EVENT = 'hardwareBackPress';
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
for (let i = _backPressSubscriptions.length - 1; i >= 0; i--) {
if (_backPressSubscriptions[i]()) {
return;
}
}
BackHandler.exitApp();
});
so when we receive the event, it will pick the events which we add in _backPressSubscriptions
before, when it reaches the end, it calls exitApp
method.
Upvotes: 2