Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-navigation: App randomly freezes when react-native Modal is shown while preventing remove screen with usePreventRemove on iOS #2125

Open
BadLice opened this issue May 9, 2024 · 2 comments
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided

Comments

@BadLice
Copy link

BadLice commented May 9, 2024

Description

I have a NativeStackNavigator with 2 screens; on the first screen i have a button to navigate to the second screen; on the second screen, i am using the usePreventRemove hook to show a confirmation modal to the user when i tries to navigate to the previous screen;

import React, {useCallback, useState} from 'react';
import {
  NavigationAction,
  useIsFocused,
  useNavigation,
} from '@react-navigation/native';
import usePreventRemove from '@react-navigation/core/src/usePreventRemove';
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {Modal, Text, View, StyleSheet} from 'react-native';
import {Button} from './Button.tsx';
import {Routes} from './StackNavigator.tsx';

export const ExitConfirmModal = () => {
  const navigation =
    useNavigation<NativeStackNavigationProp<Routes, keyof Routes>>();
  const [pendingAction, setPendingAction] = useState<NavigationAction>();
  const isFocused = useIsFocused();

  const handlePressCancel = useCallback(() => {
    setPendingAction(undefined);
  }, []);

  const handlePressConfirm = useCallback(
    (action: NavigationAction) => {
      setPendingAction(undefined);
      navigation.dispatch(action);
    },
    [navigation],
  );

  usePreventRemove(isFocused && !pendingAction, event => {
    setPendingAction(event.data.action);
  });

  if (!pendingAction) {
    return null;
  }

  return (
    <Modal
      animationType="none"
      hardwareAccelerated
      transparent
      visible
      onRequestClose={handlePressCancel}>
       <View>
        <Button onPress={() => handlePressConfirm(pendingAction)}>
          <Text>Go back</Text>
        </Button>
        <Button onPress={handlePressCancel}>
          <Text>Cancel</Text>
        </Button>
      </View>
    </Modal>
  );
};

here it is an example of the bug behaviour:

RPReplay_Final1715264311.MOV

Steps to reproduce

  1. open the app
  2. press "go to second" button to navigate to second screen
  3. press the back button to go back to previous screen
  4. when the modal open, press cancel
  5. repeat step 3
  6. sometimes the app freezes when the modal appears.

the freeze occurs randomly, so repeating steps from 3 to 5 multiple times is sometimes needed. in order to enhance the chances of the bug to occur, it is useful to run the app on a physical device (iPhone) and repeat steps from 3 to 5 multiple times rapidly. I was able to reproduce the bug only on iOS

Snack or a link to a repository

https://github.com/BadLice/modal-freeze-reproducer

Screens version

3.31.1

React Native version

0.74.1

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

Debug mode

Device

Real device

Device model

iPhone 12

Acknowledgements

Yes

@github-actions github-actions bot added Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided labels May 9, 2024
@kkafar
Copy link
Member

kkafar commented May 14, 2024

Hey @BadLice, thanks for reporting the issue.

Would you mind to check whether

haven't fixed the issue?

As this PR landed already on main you can test it by installing this library from source code by putting following in your package.json:

"react-native-screens": "software-mansion/react-native-screens#main"

@BadLice
Copy link
Author

BadLice commented May 14, 2024

hi @kkafar, thank you for your response.

unfortunately, this PR didn't fix my issue;

i created a new branch in my reproducer app resolving this library from main branch, so you can see the issue still persists: https://github.com/BadLice/modal-freeze-reproducer/tree/react-native-screens-main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS This issue is specific to iOS Repro provided A reproduction with a snack or repo is provided
Projects
None yet
Development

No branches or pull requests

2 participants