Android users reported an issue on react-navigation that is caused by a component being mounted twice where we only expect it to be mounted once (https://github.com/react-navigation/react-navigation/issues/4196). I dug into the root (no pun intended) cause and found that the problem was caused by the app root component mounting twice.
Environment:
OS: macOS High Sierra 10.13.4
Node: 9.2.0
Yarn: 1.5.1
npm: 5.7.0
Watchman: 4.7.0
Xcode: Xcode 9.3 Build version 9E145
Android Studio: 3.0 AI-171.4408382
Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.4 => 0.55.4
componentDidMount and componentWillUnmount on the root component of a new react-native init app.react-native run-androidcomponentDidMountcomponentDidMount log twice, but componentWillUnmount does not ever get logged.Root component should only ever be mounted once on app start
Root component is mounted twice on app start
+1
Uhm so it seems to be related to Android "interfering" with the React lifecycle or at least not properly unmounting when going in the background? 馃
Could it be related to the version of Android the app is running on / being targetted against (ex. v23 VS v27)?
Weirdly reminds me of this old issue https://github.com/react-navigation/react-navigation/issues/2599 which was fixed by this https://github.com/react-navigation/react-navigation/pull/3224 (just linking for reference)
OK, i face this problem right now, and i found that because our android developer change some native code, seems android developer code new another Activity!!!!
hope that helpful
I couldn't get your cloned app to build using those instructions, but I've run into a similar error in the past.
In your app/src/main/AndroidManifest.xml, try changing:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
to
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
I can reproduce this easily. Clicking the home button of the android phone, does not trigger "unmount", however subsequently clicking the app-icon from the home screen triggers my root component's "constructor" and "mount", leaving the old instance of these objects still running. Have tried @Meandmybadself 's suggestion which doesn't change this behavior.
We get this constantly in our app. We're using react-native 0.57.4, react 16.6.0 and react-navigation 2.18.2 in production. We have android:launchMode="singleTask" in our android manifest
Experiencing the exact same thing, ends up double instantiation of our router and horrible performance
We have noticed that we especially get it when we open the app through a push notification grouped by the OS (Android >8)
As in there are multiple push notifications and the OS automatically groups them by app. When we click these something weird happens with the instantiation.
Not sure if it is relevant for this issue, but I hope it helps someone debug: When we removed our splash screen the issue disappeared!
We had
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
and this caused the main activity to reinstantiate when the app came to foreground through OS grouped push notifications. We set up react-native-splash-screen instead and the problem went away
Be sure to add android:launchMode="singleTask" to activity not to application as I did first. Then I added it to activity and it works!
It still happens even with android:launchMode="singleTask" 馃槙
still occurring even though I have all the changes mentioned by @Meandmybadself
{
...
"react-native": "0.59.10",
"react-navigation": "3.9.1",
...
}
Most helpful comment
I couldn't get your cloned app to build using those instructions, but I've run into a similar error in the past.
In your
app/src/main/AndroidManifest.xml, try changing:to