Skip to content

[v4] Bottom Sheet getting snapped to -1 (closed state) in certain situations with dynamic snap points #1053

Open
@andrecrimb

Description

Bug

I'm working in a project that has a bottom sheet with 2 dynamic snapPoints (minimised, medium), when these are quickly changing, the bottom sheet snaps to -1 (closed state) and doesn't snap back.
I observed that this issue mostly happens, if in one of these changes, the snapPoints aren't ascending.

Video with sample code

Screen.Recording.2022-08-05.at.18.55.06.mov

Environment info

Library Version
@gorhom/bottom-sheet 4.2.2
react-native 0.68.2
react-native-reanimated 2.6.0
react-native-gesture-handler 2.3.2

Steps To Reproduce

  • Bottom sheet needs to have 2 dynamic snapPoints
  • SnapPoints need to be quickly changing.
  • At some point snapPoints need to be in descending order

Use sample code provided bellow to reproduce this issue.

Describe what you expected to happen:

  1. animatedIndex snaps to -1
  2. Bottom sheet disappears and doesn't snap back

Reproducible sample code

import React, { useMemo, useRef } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
import { useSharedValue } from 'react-native-reanimated';

function generateRandomInt(min: number, max: number) {
  return Math.floor(Math.random() * (max - min) + min);
}

const useSimulateDynamicSnapPoints = () => {
  const [now, setNow] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setNow(Date.now());
    }, 1);
    return () => {
      clearInterval(interval);
    };
  }, []);

  const snapPoints = useMemo(() => {
    const snapPointsNotAscending = [
      generateRandomInt(200, 250),
      generateRandomInt(100, 200),
    ];
    const snapPointsAscending = [
      generateRandomInt(100, 200),
      generateRandomInt(200, 250),
    ];

    if (Date.now() % 2 !== 0) {
      return snapPointsNotAscending;
    }
    return snapPointsAscending;
  }, [now]);
  return snapPoints;
};

const App = () => {
  const bottomSheetRef = useRef<BottomSheet>(null);
  const animatedIndex = useSharedValue(0);

  const snapPoints = useSimulateDynamicSnapPoints();

  console.log(`
SNAP_POINTS    ---> ${snapPoints}
ANIMATED_INDEX ---> ${animatedIndex.value}`);

  return (
    <View style={styles.container}>
      <BottomSheet
        ref={bottomSheetRef}
        index={1}
        snapPoints={snapPoints}
        animatedIndex={animatedIndex}
      >
        <View>
          <Text>I'm visible, please don't disappear 🙏🏽🙏🏽🙏🏽 </Text>
        </View>
      </BottomSheet>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'grey',
  },
});

export default App;

Metadata

Assignees

Labels

bugSomething isn't workingv5

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions