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

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

Open
5 of 12 tasks
BadLice opened this issue May 9, 2024 · 1 comment

Comments

@BadLice
Copy link

BadLice commented May 9, 2024

Current behavior

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>
  );
};

the bug occurs when:

  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

here it is an example of the bug behaviour:

RPReplay_Final1715264311.MOV

Expected behavior

the app does not freeze when the modal is shown

Reproduction

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

Platform

  • Android
  • iOS
  • Web
  • Windows
  • MacOS

Packages

  • @react-navigation/bottom-tabs
  • @react-navigation/drawer
  • @react-navigation/material-top-tabs
  • @react-navigation/stack
  • @react-navigation/native-stack
  • react-native-tab-view

Environment

  • I've removed the packages that I don't use
package version
@react-navigation/native 6.1.17
@react-navigation/drawer 6.6.15
@react-navigation/stack 6.3.29
@react-navigation/native-stack 6.9.26
react-native-safe-area-context 4.10.1
react-native-screens 3.31.1
react-native-gesture-handler 2.16.2
react-native-reanimated 3.10.1
react-native 0.74.1
node 21.7.1
yarn 3.6.4
Copy link

github-actions bot commented May 9, 2024

Hey! Thanks for opening the issue. Seems that this issue is related to react-native-screens library which is a dependency of React Navigation. Can you also post your issue in this repo so that it's notified to the maintainers of that library? This will help us fix the issue faster since it's upto the maintainers of that library to investigate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants