software-mansion / software-mansion/react-native-screens

iOS: RCTComponentViewRegistry: Attempt to recycle a mounted view when navigating inside tab stack while removing multiple screens

Open
#3,263 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

missing-info missing-repro platform:ios
Dominant language
TypeScript
Stars
3.7k
Forks
714
Avg merge
2d 23h
Merged PRs (30d)
71

Description

Description

When navigating with CommonActions.reset to remove multiple screens from the stack on iOS, the app crashes with:

RCTComponentViewRegistry: Attempt to recycle a mounted view

Image

This happens in two scenarios:

  1. Login redirect: After login, I reset the stack to redirect the user into the TabNavigator.
  2. Nested navigation reset: Inside a tab stack (HomeTab), when moving forward from ScreenB to ScreenC while removing ScreenA and ScreenB from the stack.

On Android this works as expected. The crash only occurs on iOS.


Navigation hierarchy
RootStack
│
├── Login
├── Otp
└── TabNavigator
    ├── HomeTab
    │   └── HomeStack
    │       ├── HomeScreen
    │       ├── ScreenA
    │       ├── ScreenB   <-- starting point
    │       └── ScreenC   <-- destination
    │
    ├── SalesTab
    │   └── SalesStack
    │       ├── SalesScreen
    │       ├── ScreenX
    │       └── ScreenY
    │
    └── SettingsTab
        └── SettingsStack
            ├── SettingsScreen
            └── ...

Environment
  • React Native: 0.81.0
  • React Navigation: 7.0.14
  • @react-navigation/native-stack: 7.2.0
  • @react-navigation/stack: 7.1.1
  • react-native-screens: ^4.9.1
  • @react-navigation/bottom-tabs: ^7.2.0
Steps to Reproduce
  1. RootStack contains:

    • AuthScreen (no AuthStack wrapper)
    • TabNavigator (no AppStack wrapper)
    • Each tab has its own stack.
  2. After login

    navigation.reset({
      index: 0,
      routes: [{ name, params }],
    });
    

    → Works fine most of the time.

  3. In HomeTab

    • Start on HomeScreen.
    • Navigate: HomeScreen → ScreenA → ScreenB.
    • From ScreenB, navigate to ScreenC while removing ScreenB and ScreenA.

    Code:

    navigation.dispatch(state => {
      const keepUntil = Math.max(0, state.routes.length - 2);
    
      const remainingRoutes = state.routes.slice(0, keepUntil).map(route => ({
        name: route.name,
        params: route.params,
      }));
    
      const routes = [...remainingRoutes, { name: 'screenC', params: {} }];
    
      return CommonActions.reset({
        ...state,
        routes,
        index: routes.length - 1,
      });
    });
    
  4. Expected stack: HomeScreen → ScreenC.

  5. Actual behavior: iOS crashes with:

    RCTComponentViewRegistry: Attempt to recycle a mounted view
    
Snack or a link to a repository

https://snack.expo.io/

Screens version

4.9.1

React Native version

0.81.0

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Fabric (New Architecture)

Build type

Debug mode

Device

Real device

Device model

iPhone 14

Acknowledgements

Yes

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the Fabric iOS crash through the CommonActions.reset and navigation.dispatch flows described, including both the login redirect and nested tab-stack reset. Trace the RCTComponentViewRegistry mounted-view recycle error in the react-native-screens integration. Done means the expected HomeScreen → ScreenC stack works without crashing on iOS, while Android behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, react-native, typescript
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.