react-native-appstate-listener icon indicating copy to clipboard operation
react-native-appstate-listener copied to clipboard

Callbacks always running twice on iPhone X when minimzing app and relaunching

Open kylethebaker opened this issue 6 years ago • 2 comments

When 'minimizing' the application on iPhone X (hard swipe up) and then selecting the icon to open the running app the onActive callback gets ran twice. This doesn't happen when going into the paging view (soft swipe up) and selecting the app.

I think this is because react native is remounting the component when you minimize/reopen in this manner, which triggers the onActive in componentDidMount and then triggers it a second time from the AppState listener.

I can't reproduce this on other iPhone versions or on android, so it seems to be isolated to iPhone X. This might be an issue (or caveat) with react native itself where it triggers a remount when minimizing/opening in this manner only on iPhone X.

Are there edge cases that are avoided by triggering the callbacks on componentDidMount? I suppose this makes onActive run when initially opening the application, but there are other instances where a component might be remounted for whatever reason and you wouldn't want your onActive callback to be called. It's possible for the onActive callback to be called several times without the app ever moving to the background.

kylethebaker avatar Mar 21 '18 15:03 kylethebaker

This component is intended as a very thin wrapper around react-native's AppState, so it's going to reflect whatever the underlying implementation is doing.

As you suspect, we call onActive in componentDidMount to handle the initial mount case; we can't really know for sure if mount time is the same as when your app is launching. Similarly, we call onBackground in componentWillUnmount for the same reason.

Do you have other callbacks besides onActive? I'm curious if one of those is being called in between the two onActive calls.

I can think of two ways of handling this case:

  1. Write your onActive (and other) callbacks in a way that makes it safe to run multiple times in a row. If you were using AppState directly, you'd have to do something similar.

  2. We'd be open to a pull request that checks the new state against the previous state and only calls the callbacks if they differ. I'm not sure if the best option would be to track the previous state as state within the component or by using AppState.currentState. I'd be curious to see whether those two approaches would yield different results in the case you encountered with the iPhone X.

randycoulman avatar Mar 21 '18 16:03 randycoulman

I think I jumped the gun on the issue being with the onActive call in componentDidMount. When using AppState directly and not calling the callbacks when mounting I still get the same behavior on iPhone X. So it would seem that when minimizing and returning to the app in this manner (hard swipe up, click on icon) the active state event is being triggered twice by AppState. This might be a bug in react native or it might be some weird caveat in the way that iPhone X handles opening/closing.

kylethebaker avatar Mar 21 '18 17:03 kylethebaker