question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[v4.0.0-alpha.25, regression] Sometimes onDismiss is not called

See original GitHub issue

Bug

Exact same bug as described in #510 reproduces on v4.0.0-alpha.25. New video demonstrating the issue:

https://user-images.githubusercontent.com/12449725/129239958-44a9ea00-e822-4871-bd12-43ecd876dbb9.mov

At first I thought that the bug reproduces only when there are multiple bottom sheets on the screen, hence the updated sample code has a button to open the second bottom sheet. However, it turns out the bug reproduces with a single bottom sheet as well, as seen in the video.

Environment info

Library Version
@gorhom/bottom-sheet 4.0.0-alpha.25
react-native 0.64.1
react-native-reanimated 2.2.0
react-native-gesture-handler 1.10.3

Steps To Reproduce

See bug description and Reproducible sample code.

Reproducible sample code

App.tsx

import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import { enableScreens } from 'react-native-screens';
import { createNativeStackNavigator, NativeStackScreenProps } from 'react-native-screens/native-stack';
import { NavigationContainer } from '@react-navigation/native';
import BottomSheet, { useBottomSheet } from './BottomSheet';

export type RootStackParamList = {
  Main: undefined;
  BottomSheet1: undefined;
  BottomSheet2: undefined;
};

enableScreens(true);
const Stack = createNativeStackNavigator<RootStackParamList>();

const MainScreen = ({navigation}: NativeStackScreenProps<RootStackParamList>) => {
  return (
    <View style={styles.container}>
      <Button
        title='Open first bottom sheet'
        onPress={() => navigation.navigate('BottomSheet1')} />
    </View>
  );
};

const BottomSheet1Screen = ({navigation}: NativeStackScreenProps<RootStackParamList>) => {
  const {bottomSheetProps} = useBottomSheet();
  return (
    <BottomSheet {...bottomSheetProps}>
      <Button
        title='Open second bottom sheet'
        onPress={() => navigation.navigate('BottomSheet2')} />
      {new Array(30).fill(null).map((_, i) => (
        <Text key={i}>Some text</Text>
      ))}
    </BottomSheet>
  );
};

const BottomSheet2Screen = () => {
  const {bottomSheetProps} = useBottomSheet();
  return (
    <BottomSheet {...bottomSheetProps}>
      <Text>Inside second bottom sheet</Text>
      {new Array(30).fill(null).map((_, i) => (
        <Text key={i}>Some text</Text>
      ))}
    </BottomSheet>
  );
};

const App = () => {
  return (
    <SafeAreaProvider>
      <NavigationContainer>
        <Stack.Navigator initialRouteName='Main'>
          <Stack.Screen
            name='Main'
            component={MainScreen} />
          <Stack.Group screenOptions={{
            stackPresentation: 'transparentModal',
            stackAnimation: 'none',
            headerShown: false
          }}>
            <Stack.Screen
              name='BottomSheet1'
              component={BottomSheet1Screen} />
            <Stack.Screen
              name='BottomSheet2'
              component={BottomSheet2Screen} />
          </Stack.Group>
        </Stack.Navigator>
      </NavigationContainer>
    </SafeAreaProvider>
  );
};

const styles = StyleSheet.create({
  container: {}
});

export default App;

BottomSheet.tsx

import React, {
  PropsWithChildren,
  Ref,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState
} from 'react';
import { LayoutChangeEvent, StyleSheet, View } from 'react-native';
import {
  BottomSheetBackdrop,
  BottomSheetModal,
  BottomSheetModalProvider,
  BottomSheetView
} from '@gorhom/bottom-sheet';
import { BottomSheetDefaultBackdropProps } from '@gorhom/bottom-sheet/lib/typescript/components/bottomSheetBackdrop/types';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useNavigation } from '@react-navigation/native';

export function useBottomSheet() {

  const bottomSheetModalRef = useRef<BottomSheetModal>(null);
  useEffect(() => {
    console.log('Presenting');
    bottomSheetModalRef.current?.present();
  }, []);

  const navigation = useNavigation();

  const dismissCallback = useRef<(() => void) | undefined>();
  const dismissBottomSheet = useCallback(() => {
    bottomSheetModalRef.current?.dismiss();
    return new Promise<void>(resolve => {
      dismissCallback.current = resolve;
    });
  }, []);

  const onDismiss = useCallback(() => {
    console.log('On dismiss');
    navigation.goBack();
    dismissCallback.current?.();
  }, []);

  return {
    dismissBottomSheet,
    bottomSheetProps: {
      bottomSheetModalRef,
      onDismiss
    }
  };

}

function Backdrop(props: BottomSheetDefaultBackdropProps) {
  return (
    <BottomSheetBackdrop
      {...props}
      appearsOnIndex={0}
      disappearsOnIndex={-1} />
  );
}

export default function BottomSheet({
  bottomSheetModalRef, onDismiss, children
}: PropsWithChildren<{
  bottomSheetModalRef?: Ref<BottomSheetModal>;
  onDismiss?: () => void;
}>) {

  const { bottom: bottomInset } = useSafeAreaInsets();
  const [contentHeight, setContentHeight] = useState(0);
  const snapPoints = useMemo(() =>
    [contentHeight + bottomInset], [contentHeight, bottomInset]);

  const handleLayout = useCallback(({ nativeEvent: { layout: { height } } }: LayoutChangeEvent) => {
    setContentHeight(height);
  }, [bottomInset]);

  return (
    <BottomSheetModalProvider>
      <BottomSheetModal
        ref={bottomSheetModalRef}
        onDismiss={onDismiss}
        snapPoints={snapPoints}
        keyboardBehavior='interactive'
        keyboardBlurBehavior='restore'
        backdropComponent={Backdrop}>
        <BottomSheetView
          onLayout={handleLayout}>
          <View style={styles.contentContainer}>
            {children}
          </View>
        </BottomSheetView>
      </BottomSheetModal>
    </BottomSheetModalProvider>
  );
}

const styles = StyleSheet.create({
  contentContainer: {
    padding: 16
  }
});

package.json

{
  "name": "bottomsheetkeyboardissues",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  },
  "dependencies": {
    "@gorhom/bottom-sheet": "^4.0.0-alpha.25",
    "@react-navigation/native": "^6.0.0-next.13",
    "react": "17.0.1",
    "react-native": "0.64.1",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-reanimated": "^2.2.0",
    "react-native-safe-area-context": "^3.2.0",
    "react-native-screens": "^3.5.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/runtime": "^7.12.5",
    "@react-native-community/eslint-config": "^2.0.0",
    "@types/jest": "^26.0.23",
    "@types/react-native": "^0.64.5",
    "@types/react-test-renderer": "^16.9.2",
    "babel-jest": "^26.6.3",
    "eslint": "^7.14.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.64.0",
    "react-test-renderer": "17.0.1",
    "typescript": "^4.3.5"
  },
  "resolutions": {
    "@types/react": "^17"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
likerncommented, Aug 15, 2021

Should I create another bug report?

0reactions
jenshanderssoncommented, Sep 14, 2021

This is still happening on Android in latest version 4.0.3, neither onClose nor onChange are being called sometimes.

Read more comments on GitHub >

github_iconTop Results From Across the Web

mui-x/CHANGELOG.md at next · mui/mui-x - GitHub
MUI X: Advanced and powerful React components for complex use-cases. - mui-x/CHANGELOG.md at next · mui/mui-x.
Read more >
material-ui/core/CHANGELOG.md - UNPKG
Each warning comes with a simple message that explains how to handle the deprecation. If no warnings are reported in the console, you...
Read more >
front-end/node_modules/@material-ui/styles/CHANGELOG.md
A way to get location (latitude and longitude), elevation, speed and other relevant data from individual satellites from the Starlink constellation.
Read more >
CHANGELOG.md · 脚本测试11/material-ui - Gitee.com
React components for faster and simpler web development. Build your own design system, or start with Material Design.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found