From d4c736b26ff86dd08cec4e0485b031e915e9b3c1 Mon Sep 17 00:00:00 2001 From: Tymoteusz Boba Date: Fri, 26 Jul 2024 14:17:15 +0200 Subject: [PATCH] fix(iOS): Crash while pushing n different screens at the same time (#2249) ## Description On Paper, while user tries to navigate to 2 or more screens at the same time, updates were batched (on async thread), resulting rerendering stack hierarchy on the next layout. In the same scenario, on Fabric, updates are not being batched, which causes crash: ``` " is pushing the same view controller instance () more than once which is not supported and is most likely an error in the application" ``` since `maybeAddToParentAndUpdateContainer` is being called to early. This PR fixes this bug by moving the logic of calling that method on `mountingTransactionDidMount` method. I've also checked if this change does not call `maybeAddToParentAndUpdateContainer` too frequent and I can't see more than one correct call there (every doubled call is being catched by `return` in conditions). Fixes #2235. ## Changes - Moved updating containers to `mountingTransactionDidMount` method. ## Screenshots / GIFs ### Before https://github.com/user-attachments/assets/24daf575-d06c-4972-9166-89454be60126 ### After https://github.com/user-attachments/assets/d377c527-0b2c-4850-b0b5-8e93dd5f25ac ## Test code and steps to reproduce You can use `Test2235.tsx` to test this change. ## Checklist - [X] Included code example that can be used to test this change - [x] Ensured that CI passes --------- Co-authored-by: Kacper Kafara --- apps/src/tests/Test2235.tsx | 107 ++++++++++++++++++++++++++++++++++++ apps/src/tests/index.ts | 1 + ios/RNSScreenStack.mm | 33 ++++++++--- 3 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 apps/src/tests/Test2235.tsx diff --git a/apps/src/tests/Test2235.tsx b/apps/src/tests/Test2235.tsx new file mode 100644 index 0000000000..4c00670dde --- /dev/null +++ b/apps/src/tests/Test2235.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import { View, StyleSheet } from 'react-native'; +import { + createNativeStackNavigator, + NativeStackNavigationProp, +} from '@react-navigation/native-stack'; +import { Button } from '../shared'; +import { NavigationContainer, ParamListBase } from '@react-navigation/native'; + +interface RouteProps { + navigation: NativeStackNavigationProp; +} + +const MainScreen = ({ navigation }: RouteProps): React.JSX.Element => ( + +