react-native-appstate-listener
react-native-appstate-listener copied to clipboard
Callbacks always running twice on iPhone X when minimzing app and relaunching
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.
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:
-
Write your
onActive
(and other) callbacks in a way that makes it safe to run multiple times in a row. If you were usingAppState
directly, you'd have to do something similar. -
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.
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.