[Bug]: BottomSheetModal getting presented again on the next screen
Version
v5
Reanimated Version
v3
Gesture Handler Version
v2
Platforms
iOS
What happened?
We have two screens, and a modal on screen 1 has a button that when pressed, dismisses the modal and navigates to screen 2.
However, the modal of screen 1 gets presented again on screen 2, without any ref.current?.present() being called:
It has to do with a useState hook that gets called too in the modal, so it might be related to a re-render operation of screen 1.
Note: the provided Snack does not run for some reason that I don't understand but have already reported. Just paste the whole App.tsx into a local project and run it from there.
Note that the problem disappears if you enable the setTimeout on line 57.
Reproduction steps
- Take the code from the reproduction example here: https://snack.expo.dev/@yolpsoftware/bottomsheetmodal-getting-presented-again-on-the-next-screen
- If you cannot run the Snack, paste the code (just one file, App.tsx) into a local project and run it from there
Reproduction sample
https://snack.expo.dev/@yolpsoftware/bottomsheetmodal-getting-presented-again-on-the-next-screen
Relevant log output
same probleme for me on rerender
@yolpsoftware a working code
import React, {useCallback, useRef, useState} from 'react';
import {
BottomSheetModal,
BottomSheetModalProvider,
BottomSheetView,
} from '@gorhom/bottom-sheet';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {Text, View} from 'react-native';
import {GestureHandlerRootView, Pressable} from 'react-native-gesture-handler';
const Screen1 = (props: any) => {
const modalRef = useRef<BottomSheetModal>(null);
const [modalIsOpen, setModalIsOpen] = useState(false);
const onModalOpenOrClose = useCallback(
(isOpen: boolean) => {
if (!isOpen) {
modalRef.current?.dismiss();
}
setModalIsOpen(isOpen);
},
[modalRef],
);
const onModalPressed = useCallback(() => {
props.navigation.push('Screen2', {});
modalRef.current?.dismiss();
}, [props]);
const openModal = useCallback(() => {
modalRef.current?.present();
}, []);
return (
<View style={{justifyContent: 'center', padding: 100}}>
<Pressable onPress={openModal}>
<Text>Click me!</Text>
</Pressable>
<Modal
onModalPressed={onModalPressed}
onOpenOrClose={onModalOpenOrClose}
ref={modalRef}
/>
</View>
);
};
const Screen2 = () => {
return (
<View style={{justifyContent: 'center', padding: 100}}>
<Text>Screen 2</Text>
</View>
);
};
interface ModalProps {
onModalPressed?: () => void;
onOpenOrClose: (isOpen: boolean) => void;
}
const Modal = React.forwardRef<BottomSheetModal, ModalProps>((props, ref) => {
const [sheetIsOpen, setSheetIsOpen] = React.useState(false);
React.useEffect(() => {
props.onOpenOrClose(sheetIsOpen);
}, [sheetIsOpen]);
const onChange = useCallback(
(index: number) => {
//setTimeout(() => { // if you enable this timeout here, the problem will go away
setSheetIsOpen(index >= 0);
//}, 50);
},
[setSheetIsOpen],
);
return (
<BottomSheetModal
ref={ref}
enablePanDownToClose={true}
enableDynamicSizing={true}
onChange={onChange}>
<BottomSheetView>
<View style={[{backgroundColor: 'white', height: 200}]}>
<View>
<Pressable onPress={props.onModalPressed}>
<Text>Click me!</Text>
</Pressable>
</View>
</View>
</BottomSheetView>
</BottomSheetModal>
);
});
const Stack = createStackNavigator();
const App = () => {
return (
<GestureHandlerRootView style={{flex: 1}}>
<NavigationContainer>
<BottomSheetModalProvider>
<Stack.Navigator>
<Stack.Screen
name="Screen1"
component={Screen1 as any}
options={{animation: 'fade'}}
/>
<Stack.Screen
name="Screen2"
component={Screen2 as any}
options={{animation: 'fade'}}
/>
</Stack.Navigator>
</BottomSheetModalProvider>
</NavigationContainer>
</GestureHandlerRootView>
);
};
export default App;
can confirm, happens to me as well
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
not stale
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
not stale
Not stale at all :)
It was never stale :(
not stale 😓
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Not stale
Not stale
not stale
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
This issue was closed because it has been stalled for 5 days with no activity.
not stale