gorhom / react-native-bottom-sheet

A performant interactive bottom sheet with fully configurable options 🚀
https://gorhom.dev/react-native-bottom-sheet/
MIT License
6.77k stars 745 forks source link

[v4] | [v2] Unable to set initial index to be open #1689

Closed BethThomas141 closed 2 weeks ago

BethThomas141 commented 9 months ago

Bug

We've just upgraded the bottom-sheet version in our app from v4.4.7 to v4.6.0. On doing this we now get the following error anywhere we use the bottom sheet: 'index' was provided but out of the provided snap points range! expected value to be between -1, 0. We have four snap points passed into the drawer: -1 (hidden), 0 (closed), 1 (partially open), 2 (fully open). We want the drawer to start partially open, so we want index = 1 on the Bottom sheet component. However, it seems like we can only pass in index={-1} or index={0} otherwise we see this error.

Environment info

Library Version
@gorhom/bottom-sheet 4.6.0
react-native 0.72.6
react-native-reanimated 3.5.4
react-native-gesture-handler 2.12.0

Steps To Reproduce

  1. Implement a bottom sheet and pass in array of at least two snapPoints. Pass in an index of 1.

Describe what you expected to happen:

  1. The Bottom sheet starts at snapPoint 1 (height 600) on first load. Instead we get the error 'index' was provided but out of the provided snap points range! expected value to be between -1, 0.

Reproducible sample code

import React, { useMemo, useRef, useCallback } from 'react';
import { View, StyleSheet } from 'react-native';
import BottomSheet, { enableLogging } from '@gorhom/bottom-sheet';
import List from './components/List';
import SearchHandle from './components/SearchHandle';
import Button from './components/Button';

enableLogging();

const App = () => {
  // refs
  const bottomSheetRef = useRef(null);

  // variables
  const snapPoints = useMemo(() => [200, 400], []);

  // callbacks
  const handleExpandPress = useCallback(() => {
    bottomSheetRef.current?.expand();
  }, []);
  const handleCollapsePress = useCallback(() => {
    bottomSheetRef.current?.collapse();
  }, []);
  const handleClosePress = useCallback(() => {
    bottomSheetRef.current?.close();
  }, []);

  return (
    <View style={styles.container}>
      <Button onPress={handleExpandPress} title="Expand" />
      <Button onPress={handleCollapsePress} title="Collapse" />
      <Button onPress={handleClosePress} title="Close" />
      <BottomSheet
        ref={bottomSheetRef}
        snapPoints={snapPoints}
        keyboardBehavior="interactive"
        index={1}
        handleComponent={SearchHandle}
        animateOnMount={true}
        android_keyboardInputMode="adjustPan">
        <List type="FlatList" />
      </BottomSheet>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingVertical: 64,
    justifyContent: 'flex-start',
    backgroundColor: '#222',
  },
});

export default App;
jdnichollsc commented 8 months ago

@BethThomas141 is expand method working from your side w/ a useEffect?

gorhom commented 7 months ago

@BethThomas141 i have tested your provided sample code and it worked as expected, no error were thrown

andrecrimb commented 7 months ago

Same issue.

alcantara2509 commented 6 months ago

Same issue.

indiaabbott commented 6 months ago

same issue here! i think its because the library internally calculates container height if its not provided as props, and when this happens it sometimes normalises the snap points to only return an array with a single snap point. The relevant code is here.

Then when you e.g. snapToIndex to an index that is greater than 0, you see this error.

So I think a workaround is to provide a container height, however Im just trying to figure out now what value I should be providing for this... 😅

@gorhom

abcarlisle commented 5 months ago

I am seeing this too, running on expo with "@gorhom/bottom-sheet": "^4.6.1", "react-native-reanimated": "~3.6.2",

After initial render everything works as expected. However on the first render the bottom sheet does not appear. Adding containerHeight did not fix issue. I have tried using snaptoindex and expand in a useEffect but that did not work either.

abcarlisle commented 5 months ago

same issue here! i think its because the library internally calculates container height if its not provided as props, and when this happens it sometimes normalises the snap points to only return an array with a single snap point. The relevant code is here.

Then when you e.g. snapToIndex to an index that is greater than 0, you see this error.

So I think a workaround is to provide a container height, however Im just trying to figure out now what value I should be providing for this... 😅

@gorhom

Did this work for you? I added container height and still no luck.

abcarlisle commented 5 months ago

I am seeing this too, running on expo with "@gorhom/bottom-sheet": "^4.6.1", "react-native-reanimated": "~3.6.2",

After initial render everything works as expected. However on the first render the bottom sheet does not appear. Adding containerHeight did not fix issue. I have tried using snaptoindex and expand in a useEffect but that did not work either.

Okay I did some digging and found that i needed to pass in handleHeight={windowHeight} and that allowed

useEffect(() => sheetRef.current?.snapToIndex(1),[])

to open up the bottom sheet on the intial render.

index={1} still didn't work but at least this is a work around for me.

abcarlisle commented 5 months ago

I am seeing this too, running on expo with "@gorhom/bottom-sheet": "^4.6.1", "react-native-reanimated": "~3.6.2", After initial render everything works as expected. However on the first render the bottom sheet does not appear. Adding containerHeight did not fix issue. I have tried using snaptoindex and expand in a useEffect but that did not work either.

Okay I did some digging and found that i needed to pass in handleHeight={windowHeight} and that allowed

useEffect(() => sheetRef.current?.snapToIndex(1),[])

to open up the bottom sheet on the intial render.

index={1} still didn't work but at least this is a work around for me.

Welp I guess that work around only works if I used this as a patch. Hahaha. Will stop replying to myself now. https://github.com/gorhom/react-native-bottom-sheet/pull/1694

indiaabbott commented 5 months ago

same issue here! i think its because the library internally calculates container height if its not provided as props, and when this happens it sometimes normalises the snap points to only return an array with a single snap point. The relevant code is here. Then when you e.g. snapToIndex to an index that is greater than 0, you see this error. So I think a workaround is to provide a container height, however Im just trying to figure out now what value I should be providing for this... 😅 @gorhom

Did this work for you? I added container height and still no luck.

You’re right, this didn’t end up working for me.

What we have done instead is to use the ‘useAnimatedReaction’ hook from the Reanimated lib - it watches the bottom sheet library’s internals to check when the snap points are ready (you can get animatedSnapPoints from useBottomSheetInternal). As we know they are normalised to -999, but then this changes when the sheet is ready.

Once the sheet is ready, we set a state variable ‘sheetReady’ to true, and then in a useEffect call snapToIndex(openIndex). We start all our sheets in the closed state (index -1) and only expand to open state when the sheet is ready, giving the effect that the sheet is mounting open 🥴

so yes, agree that it’s an issue that you can’t pass index > 0 to the sheet as a starting prop 😔

github-actions[bot] commented 4 months ago

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.

andrecrimb commented 4 months ago

👍🏽

BethThomas141 commented 3 months ago

In case useful to anyone, I have a PR open here https://github.com/gorhom/react-native-bottom-sheet/pull/1694 that has a fix in, I've patched the package locally so I can use it.

adnen-chouibi commented 2 months ago

I don't have the exact solution for this issue, but I can share something that might help you start investigating.

I encountered an error when copying the exact same code from one component that works fine to another. The error message after moving to new component was:

[Invariant Violation: 'index' was provided but out of the provided snap points range! expected value to be between -1, 0]

Interestingly, the error disappeared without changing any code. I just changed the position of in my component.

ghacosta commented 2 months ago

Another finding, is sending one value on the snapPoints array, this error happens, if sending more than one, this works taking latest value.

<BottomSheetModal ref={modalRef} index={1} snapPoints={['75%']}> //raise error

<BottomSheetModal ref={modalRef} index={1} snapPoints={['50%', '75%']}> //works opening straight to 75%
github-actions[bot] commented 1 month ago

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.

sdmotameni commented 1 month ago

Still experiencing this issue, but am using reanimated v3.

github-actions[bot] commented 3 weeks ago

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.

github-actions[bot] commented 2 weeks ago

This issue was closed because it has been stalled for 5 days with no activity.