React-native-screens: RNScreensNavigationController is pushing the same view controller instance more than once

Created on 26 Jan 2021  路  15Comments  路  Source: software-mansion/react-native-screens

Description

We are seeing the following crash quite frequently on iOS since we started to use react-native-screens/createNativeStackNavigator. Any help would be much appreciated.

Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0

Application Specific Information:
<RNScreensNavigationController: 0x1038e6800> is pushing the same view controller instance (<RNSScreen: 0x12f123e20>) more than once which is not supported and is most likely an error in the application

Thread 0 Crashed:
0   CoreFoundation                  0x3259749d8         __exceptionPreprocess
1   libobjc.A.dylib                 0x34e15ab50         objc_exception_throw
2   UIKitCore                       0x3298bc6c0         -[UINavigationController pushViewController:transition:forceImmediate:]
3   UIKitCore                       0x32a4dbfb4         -[_UIAfterCACommitBlock run]
4   UIKitCore                       0x32a041a64         _runAfterCACommitDeferredBlocks
5   UIKitCore                       0x32a030f94         _cleanUpAfterCAFlushAndRunDeferredBlocks
6   UIKitCore                       0x32a062564         _afterCACommitHandler
7   CoreFoundation                  0x3258f3878         __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
8   CoreFoundation                  0x3258edf4c         __CFRunLoopDoObservers
9   CoreFoundation                  0x3258edbf0         CFRunLoopRunSpecific
10  GraphicsServices                0x3533f9594         GSEventRunModal
11  UIKitCore                       0x32a0323d4         -[UIApplication _run]
12  UIKitCore                       0x32a037954         UIApplicationMain
13  ########                        0x200d3d5d4         main (main.m:7)

Steps To Reproduce

We see this crash in our Sentry issues but don't know how to reproduce it yet.

Package versions

  • React: 16.13.1
  • React Native: 0.63.3
  • React Native Screens: 2.16.1
  • React Navigation: 4.4.3
iOS native-stack

Most helpful comment

I know my information is very limited at this point. Thanks for sharing your thoughts on this.

All 15 comments

I am afraid we cannot do much without the reproduction. From the crash description, it looks like it might be caused by pushing screens too fast leading to some wrong state of navigation stack with 2 same screens, but I cannot say much more.

I know my information is very limited at this point. Thanks for sharing your thoughts on this.

I have the same issue, may this help

image

@msvargas are you able to reproduce it on a simple example?

@msvargas are you able to reproduce it on a simple example?

At the time, I check it occurs rarely when switching auth flow, like this: https://reactnavigation.org/docs/auth-flow/#define-our-screens after user log in and redirect to "Home", I have to errors log with the same iOS version 14.3

So could you post this reproduction? It does not need to be fully deterministic, it needs to be reproducible in finite steps.

Just popping in to say I have the same issues, using the same auth navigator setup that @msvargas mentioned above. I started with @infinitered's Ignite starter which uses both react-native-screens and react-navigation.

I'm blocked from launching our app until this is resolved, and I've spent a number of hours trying to debug this. The fact others have cropped up with this issue recently makes me think it might be an Ignite navigation boilerplate or a react-native-screens error, but I'm still trying to get to the bottom of it. Will follow up with repro etc soon.

The error happens here in CallbackScreen.tsx:

type props = StackScreenProps<StackOneParams, 'callback'>

...

useEffect(() => {
  if (conditional) {
    props.navigation.navigate('onboard')
  }
}, [props])

return <View><ActivityIndicator /></View>

When running from xcode (testing on device), the CallbackScreen remains with the spinning activity indicator (ie. no navigation) and Xcode reports the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '<RNScreensNavigationController: 0x10d017e00> is pushing the same view controller instance (<RNSScreen: 0x1089572f0>) more than once which is not supported and is most likely an error in the application : com.appgoeshere'

But after I close and reopen the app on my device (so the device is now communicating with the RN server on my mac _without going through xcode_), my console logs shows it successfully navigating to our OnboardingScreen and actually running our useEffect() hooks - but then it crashes without any kind of error.
Screenshot 2021-02-20 at 23 30 21

Is there a reason why Xcode would potentially stop a navigation performing whilst in debugging mode?

Can you provide a snack/repo with minimal configuration needed to reproduce the issue?

I've managed to reproduce this issue with the following code

import React, {useEffect} from 'react';
import {StyleSheet, Button, View, Text} from 'react-native';
import {enableScreens} from 'react-native-screens';
import {createNativeStackNavigator} from 'react-native-screens/native-stack';

enableScreens();

const MainScreen = ({navigation}) => {
  useEffect(() => {
    navigation.navigate('Modal')
  }, [])

  return (
    <View style={styles.screen}>
      <Text>Issue 791</Text>
    </View>
  )
}

const PushScreen = ({navigation}) => (
  <View style={styles.screen}>
    <Button onPress={() => navigation.push('Push')} title="Mash this button" />
  </View>
);

const Stack = createNativeStackNavigator();

const App = () => (
  <Stack.Navigator>
    <Stack.Screen
      name="Main"
      component={MainScreen}
    />
    <Stack.Screen
      name="Push"
      component={PushScreen}
    />
    <Stack.Screen
      name="Modal"
      component={PushScreen}
      options={{ stackPresentation: 'modal'}}
    />
  </Stack.Navigator>
);

const styles = StyleSheet.create({
  screen: {
    ...StyleSheet.absoluteFillObject,
    flex: 1,
    paddingTop: 200,
    alignItems: 'center',
  },
});

export default App;

This error occurs when you push a 'normal' screen under a modal. Inside modals only pushing modals is supported. Could you check if it's the case within your app?

Can you check if https://github.com/software-mansion/react-native-screens/pull/839 fixes your issues @birgernass @msvargas @lucasjohnston ?

Issue validator

The issue is valid!

@WoLewicki Is "modal" a specific construct in RNScreens (ie. the stackPresentation: 'modal' param) or do you mean modal in terms of general function / design? More context would be appreciated :)
We aren't using the stackPresentation: 'modal' property anywhere and are not using modals, but might well be navigating between screens incorrectly. Happy to share our navigation config in more detail privately if useful.

I found that there was a bug in our state/store logic which was causing the crash. The issue went away once that was solved, but I have a feeling this RNScreens bug is still lurking in the background + am still unsure about why there was such a big difference in behaviour between Xcode + on device.

By modal I meant all of RNScreens stackPresentation options different than push, so basically the native iOS modals used and handled by RNScreens, sorry for not communicating it clear enough.

I added some context in the description of #839, there might be a flow where you post new transitions during the ongoing transition, and it might result (and it does in the reproduction https://github.com/software-mansion/react-native-screens/issues/791#issuecomment-785701873) in pushing the same VC twice. It can occur if you use navigating as a response to events.

It is indeed weird that there could be difference when using Xcode.

Also, I think the structure of the navigation does not seem as a private configuration, and it would be best if it was available for everyone to test it and maybe find the solution, but if it is not possible for you for some reason, you can share it privately.

I updated the #839 to a better solution (hopefully). I also added a test case where the crash could be reproduced each time without the native changes. Could you check if applying it fixes your issues?

Was this page helpful?
0 / 5 - 0 ratings