software-mansion / react-native-screens

Native navigation primitives for your React Native app.
https://docs.swmansion.com/react-native-screens/
MIT License
3.11k stars 521 forks source link

`ScreenStack.onDismissed` incorrectly called after a navigating back, causing double-back navigation in old architecture #2525

Open levibuzolic opened 6 days ago

levibuzolic commented 6 days ago

Description

In a navigator with 2 card modals in the stack, calling navigation.goBack() causes a double-pop (navigating back 2 screens, instead of 1). This only occurs on the old architecture, switching to the new architecture has the correct behaviour.

It appears that the second POP action is being dispatched from ScreenStack.onDismissed here: https://github.com/react-navigation/react-navigation/blob/5da190167882859bb3356a84de42be3ca540ef99/packages/native-stack/src/views/NativeStackView.native.tsx#L538-L546

Steps to reproduce

  1. Press Open modal
  2. Expect screen One
  3. Press Open second modal
  4. Expect screen Two
  5. Press Back
  6. Expect screen One 🚫

Snack or a link to a repository

https://github.com/levibuzolic/model-navigation-repro

Same code as a Expo Snack, but does not reproduce the issue now that Expo Snack is running the new architecture.

Screens version

4.2.0

React Native version

0.76.2

Platforms

iOS

JavaScript runtime

Hermes

Workflow

Expo managed workflow

Architecture

Paper (Old Architecture)

Build type

Debug mode

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

Old Architecture

Demonstrates broken behaviour, two models are removed with a single goBack() action.

https://github.com/user-attachments/assets/d090d001-98d7-4392-a2b7-14c1494c60fd

New Architecture

Shows correct behaviour, only one screen removed.

https://github.com/user-attachments/assets/8c1af769-a05d-48fd-91b3-a7a4e6635b65

kkafar commented 6 days ago

Thanks for reporting!

blytung commented 5 days ago

Ah have the same problem, didn't know if it was expected or not. Spent like 20h trying to solve it and have some hacky workarounds.

vadim-isakov commented 1 day ago

For a while, I resolved the issue by downgrading react-native-screens to version 3.35.0. Initially, this required downgrading several peer dependency libraries as well. However, downgrading all React Native libraries led to additional bugs, so I decided to limit the downgrades to just the following:

{
    "@react-navigation/native-stack": "6.6.1",
    "react-native-screens": "3.35.0"
}

This approach seems to be working so far.

To ensure compatibility, remember to check dependencies using the command: npx check-peer-dependencies