React-native: BackAndroid removeEventListener not removing listener

Created on 12 Dec 2015  路  16Comments  路  Source: facebook/react-native

My code snipped is as below. The issue is that if I put the code below in multiple pages (n pages), the navigator will pop n times when the back button is clicked. I am not sure if this the remove listener function issue or it's meant to this this way. I will need to handle a back button action in one page specifically so would need to insert the listener to that page. Thanks a lot!

I am using RN 0.15.0 Android on Mac OS

navigatorPop(){
this.props.navigator.pop();
return true;
},
componentDidMount(){
BackAndroid.addEventListener('hardwareBackPress', this.navigatorPop)
},
componentWillUnmount(){
BackAndroid.removeEventListener('hardwareBackPress',this.navigatorPop)
},

Locked

Most helpful comment

@ivesy85 .bind returns a new function. So the function you're passing to BackAndroid.removeEventListener is not the same as the one you passed to BackAndroid.addEventListener. Try something like the following,

    constructor(props) {
        this._pasEditUnmountFunction = this._pasEditUnmountFunction.bind(this);
    }

    componentDidMount() {
        BackAndroid.addEventListener('hardwareBackPress', this._pasEditUnmountFunction);
    }

    componentWillUnmount() {
        BackAndroid.removeEventListener('hardwareBackPress', this._pasEditUnmountFunction);
    }

    _pasEditUnmountFunction() {
        if (this.props.getSelectedTab() === 'recent') {
            this.props.mainNav.replace({ id: 'recentPas' });
        }
    }

All 16 comments

Hey golorry, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If this is a feature request or a bug that you would like to be fixed by the team, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • If you don't know how to do something or not sure whether some behavior is expected or a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • We welcome clear issues and PRs that are ready for in-depth discussion; thank you for your contributions!

I'm trying to remove the listener using BackAndroid.removeEventListener but it's not removing it. Are you sure you managed to remove it correctly?

Never mind, a bind problem. Thanks!

@alvaromb I think I may be having the same issue as you. How did you solve this. My code in this area is as follows.

componentDidMount() {
        console.log('mount');
        BackAndroid.addEventListener('hardwareBackPress', this.pasEditUnmountFunction.bind(this));
    }

    componentWillUnmount() {
        console.log('unMount');
        BackAndroid.removeEventListener('hardwareBackPress', this.pasEditUnmountFunction.bind(this));
    }

    pasEditUnmountFunction() {
        console.log('perform function');
        if(this.props.getSelectedTab() == 'recent') {
            this.props.mainNav.replace({id: 'recentPas'});
        }
    }

@ivesy85 .bind returns a new function. So the function you're passing to BackAndroid.removeEventListener is not the same as the one you passed to BackAndroid.addEventListener. Try something like the following,

    constructor(props) {
        this._pasEditUnmountFunction = this._pasEditUnmountFunction.bind(this);
    }

    componentDidMount() {
        BackAndroid.addEventListener('hardwareBackPress', this._pasEditUnmountFunction);
    }

    componentWillUnmount() {
        BackAndroid.removeEventListener('hardwareBackPress', this._pasEditUnmountFunction);
    }

    _pasEditUnmountFunction() {
        if (this.props.getSelectedTab() === 'recent') {
            this.props.mainNav.replace({ id: 'recentPas' });
        }
    }

Why remove the listener, you can just write some judgement to avoid code being executed:
bind: function() {
if (navigator.getCurrentRoutes().length > 1) {
navigator.pop();
return true;
}
var time = (new Date()).getTime();
if (time - Globals.timer > 3000) {
Globals.timer = time;
ToastAndroid.show('Click Again to exit', ToastAndroid.SHORT);
return true;
}
return false;
},

@GHACCT , I am facing the same issue with my application which is a UWP application which uses react-native (https://github.com/ReactWindows/react-native-windows#opening-issues)
Can you please tell me how you rectified this.

@satya164 Thank you very much....have been trying to achieve it all the day

@satya164 your Solution Worked. Thanks

@satya164 Thanks! Save my time :+1:

@satya164 Thank you very much!!!!

@satya164 Thanks a lot!!

@satya164 this should go into the documentation some how. I know .bind is not react native specific, but that it returns a new function, which again makes the remove listener function not work. Is something that should be documented.

Binding the function in constructor is still not working for me. I press hardware back button and it pops out all screens. Any other solution?

@cstehreem you're probably not invoking componentWillUnmount(), use console logs to test that case

I wanted to remove listener in some dummy function, not in componentWillUnmount.

removeListener(){
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}

something like this... and call this function when I navigate...
this function gets called but the listener is not removed.
Any help appreciated

Was this page helpful?
0 / 5 - 0 ratings