Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

React Native: AppState.addEventListener registering duplicate events on resume when tapping a notification

Ask Question

I have code which I want to run when my app resumes from the background. To this end, I register an event using AppState.addEventListener().

  const handleAppStateChange = () => {
    console.log('Do stuff')
  constructor(props: Props) {
    super(props)
    AppState.addEventListener('change', this.handleAppStateChange)
  componentWillUnmount() {
    AppState.removeEventListener('change', this.handleAppStateChange)

When I normally exit the app and resume, it prints 'do stuff' as expected, however (and here is the issue), when the app is minimised and I tap on a notification, the app will print 'Do stuff' twice.

I have figured out it's because when I tap a notification, it seems to re-run the app (including the constructor part), which means it creates a second event listener...

So, does anyone know either why it's doing that when tapping on a notification and if I can prevent it (using react-native-push-notification plugin), or alternatively if there is a way I can ensure that duplicate events are not registered?

This is happening on my Android physical device, not sure if it's an iOS issue as well, but just thought I would check if anyone knew if this was possible)

componentDidMount is propably better for your event subscription.Maybe thats also your entire problem why it's sometimes get subscribed but not unsubscribed. – DogeAmazed Feb 1, 2019 at 15:52 I did test this thank you, but I think the problem is not necessarily related to it (but you can argue it's probably a better place to put it) – JackDev Feb 1, 2019 at 17:04

So after much agonising, I have managed to come up with a solution. It's not great, but gets the job done for now.

if (AppState._eventHandlers.change.size === 0) {
  AppState.addEventListener('change', this.handleAppStateChange)

I feel the AppState page https://facebook.github.io/react-native/docs/appstate, is woefully inadequate, and that is why the only option I could see right now is this private method. Will try and follow up with the team if this could be improved, because it would make sense that in some cases you don't want duplicated events to be registered.

Now I have this tsc error: error TS2339: Property '_eventHandlers' does not exist on type 'AppStateStatic'. – dazza5000 Dec 26, 2019 at 17:30

The answer above is still the correct one, however it might cause crashes on iOS 13. It works fine on Android.

My suggestion is to explicitly check for Android:

if (Platform.OS === 'android' && AppState._eventHandlers.change.size === 0)
if (AppState._eventHandlers.change.size === 0) {

AppState.addEventListener('change', this.handleAppStateChange) I got this error :

Now I have this tsc error: error TS2339: Property '_eventHandlers' does not exist on type 'AppStateStatic'.

So,I rollbacked it and then I resolved AppState.addEventListener registering duplicate events on resume when tapping a notification, by changing arrow function to function in this way:

AppState.addEventListener('change', controlSocketConnection);
function controlSocketConnection() { // some code }
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.