Modal reopens while dismissing if it gets re-rendered while closing
See original GitHub issueBug
This is a bit more precise version (with reproducible code sample) of #191.
If your handler call dismiss
but also triggers the modal to get updated, then modal doesn’t get dismissed, it reopens.
https://user-images.githubusercontent.com/6768840/104815091-e1482c00-5855-11eb-9797-048efd23f69e.mov
Full repro is noted below (thought it only contains 1 line diff from the example app), and related screen code is as below.
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import { BottomSheetModal, BottomSheetView } from '@gorhom/bottom-sheet';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Button from '../../components/button';
import withModalProvider from '../withModalProvider';
const DynamicSnapPointExample = () => {
// state
const [count, setCount] = useState(0);
const [contentHeight, setContentHeight] = useState(0);
// hooks
const bottomSheetRef = useRef<BottomSheetModal>(null);
const { bottom: safeBottomArea } = useSafeAreaInsets();
// variables
const snapPoints = useMemo(() => [contentHeight], [contentHeight]);
// callbacks
const handleIncreaseContentPress = useCallback(() => {
setCount(state => state + 1);
}, []);
const handleDecreaseContentPress = useCallback(() => {
setCount(state => Math.max(state - 1, 0));
}, []);
const handlePresentPress = useCallback(() => {
bottomSheetRef.current?.present();
}, []);
const handleDismissPress = useCallback(() => {
// NOTE: This setCount call triggers the issue
setCount(state => state + 1);
bottomSheetRef.current?.dismiss();
}, []);
const handleOnLayout = useCallback(
({
nativeEvent: {
layout: { height },
},
}) => {
setContentHeight(height);
},
[]
);
// styles
const contentContainerStyle = useMemo(
() => ({
...styles.contentContainerStyle,
paddingBottom: safeBottomArea,
}),
[safeBottomArea]
);
const emojiContainerStyle = useMemo(
() => ({
...styles.emojiContainer,
height: 50 * count,
}),
[count]
);
// renders
const renderBackground = useCallback(
() => <View style={styles.background} />,
[]
);
return (
<View style={styles.container}>
<Button
label="Present"
style={styles.buttonContainer}
onPress={handlePresentPress}
/>
<Button
label="Dismiss"
style={styles.buttonContainer}
onPress={handleDismissPress}
/>
<BottomSheetModal
ref={bottomSheetRef}
index={0}
snapPoints={snapPoints}
backgroundComponent={renderBackground}
>
<BottomSheetView
style={contentContainerStyle}
onLayout={handleOnLayout}
>
<Text style={styles.message}>
Could this sheet modal resize to its content height ?
</Text>
<View style={emojiContainerStyle}>
<Text style={styles.emoji}>😍</Text>
</View>
<Button
label="Yes"
style={styles.buttonContainer}
onPress={handleIncreaseContentPress}
/>
<Button
label="Maybe"
style={styles.buttonContainer}
onPress={handleDecreaseContentPress}
/>
</BottomSheetView>
</BottomSheetModal>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
},
background: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'white',
},
buttonContainer: {
marginBottom: 6,
},
contentContainerStyle: {
paddingTop: 12,
paddingHorizontal: 24,
backgroundColor: 'white',
},
message: {
fontSize: 24,
fontWeight: '600',
marginBottom: 12,
},
emoji: {
fontSize: 156,
textAlign: 'center',
alignSelf: 'center',
},
emojiContainer: {
overflow: 'hidden',
justifyContent: 'center',
},
});
export default withModalProvider(DynamicSnapPointExample);
Environment info
Library | Version |
---|---|
@gorhom/bottom-sheet | 2.0.4 |
react-native | 0.63.4 |
react-native-reanimated | 1.13.2 |
react-native-gesture-handler | 1.9.0 |
Steps To Reproduce
- Clone the repo below
- Run the example app and select
MODAL > Dynamic Snap Point
example - Press
Present
- Press
Dismiss
Describe what you expected to happen:
- Modal closes without reopening
Reproducible sample code
https://github.com/heejongahn/react-native-bottom-sheet
You can verify this behavior with example/src/sceens/modal/DynamicSnapPointExample.tsx
. (diff from original example)
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:20 (5 by maintainers)
Top Results From Across the Web
Prevent modal from closing after re-render in react
Something is obviously going very wrong here, the Modal should not close. As a workaround you could do something like this:
Read more >Build a simple Modal Component with React - Bits and Pieces
This will render whatever is passed to this component, which is just perfect for a dynamic modal. Close the modal. After opening a...
Read more >Build a complete Modal Component with React Hooks
If the user uses the ESCAP key on his keyboard, then the modal closes. The result is: React Modal close. The CSS !...
Read more >Visualforce component as modal dialog - Salesforce Developers
When you are using reRender, you are rendering the content, so when you have "rendered" on the same level, it is not evaluated....
Read more ><af:dialog> - Oracle Help Center
Server-side listeners can be registered with the parent af:popup component and will be invoked when the dialog is dismissed using a closed dialog...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Same problem here using tab bar, when I navigate from the tab that have the bottom sheet (and its closed) and then comeback to the same tab, the bottom sheet appears open. The problem is only with Android.
this should be fixed with
v2.0.7
🎉