react-native-bottom-sheet icon indicating copy to clipboard operation
react-native-bottom-sheet copied to clipboard

[Bug]: BottomSheetFlashList doesn't respond to scrolling in `v5.1.5+`

Open AlexanderHott opened this issue 7 months ago • 28 comments

Version

v5

Reanimated Version

v3

Gesture Handler Version

v2

Platforms

Android

What happened?

When using BottomSheetFlashList, the scroll view doesn't respond to scrolling.

Reproduction steps

(The template https://snack.expo.dev/@gorhom/bottom-sheet---issue-reproduction-template didn't work for me. There was some issue with peer dependencies on @types/* packages, but it couldn't install them)

  • Make sure "@gorhom/bottom-sheet": "5.1.4" in package.json
  • bun i
  • bunx expo run:android or bunx expo run:ios

Scrolling works

  • Upgrade to "@gorhom/bottom-sheet": "5.1.5" or "@gorhom/bottom-sheet": "5.1.6" in package.json
  • bun i
  • bunx expo run:android or bunx expo run:ios

Scrolling no longer works

Reproduction sample

https://github.com/AlexanderHott/gorhom-bottom-sheet-no-scroll

Relevant log output


AlexanderHott avatar Jun 10 '25 06:06 AlexanderHott

It somehow seems to work in the examples directory of the project. I got it to compile locally, and that works. However, installing from the master branch on my example above doesn't work.

    "@gorhom/bottom-sheet": "git+https://github.com/gorhom/react-native-bottom-sheet.git#master",

Am I missing something from the examples?

AlexanderHott avatar Jun 10 '25 06:06 AlexanderHott

Same for me with SectionList, I'm unable to scroll when I update to v5 (v4 is working correctly)

raffiot avatar Jun 10 '25 15:06 raffiot

+1

CostasCF avatar Jun 11 '25 11:06 CostasCF

I can't either.

habasa avatar Jun 13 '25 01:06 habasa

Hey 👋 I can confirm that I experience the same scrolling issues on flashlists in 5.1.6 as well as sizing issues when embedded in bottom sheets.

WARN FlashList's rendered size is not usable. Either the height or width is too small (<2px). Please make sure that the parent view of the list has a valid size. FlashList will match the size of the parent.

This is making my lists not visible anymore in those sheets and I do appreciate that even though this is a flashlist warning I can confirm that I did not have nor the warning nor the sheet visibility issue in 5.1.5.

It probably comes from this commit, no? https://github.com/gorhom/react-native-bottom-sheet/commit/53974786a18aceab1cc15def1b29c94ef93002e3 - hope it helps 🙏

michaelvitello avatar Jun 17 '25 21:06 michaelvitello

The problem basically being that the underlying native ScrollView is set to the height of the content. When the scrollview's size is equal to the content size there is nothing to scroll, thus no scroll will happen.

As you can see here the layout height is 2105, which is equal to the content height:

Image

This seems to be a bug with react-native's yoga layout calculation. However, as it was working before, it must be something specific to the view hierarchy changes that happened in this commit:

  • https://github.com/gorhom/react-native-bottom-sheet/commit/209886dc8ec0d5c19c7d2b72226ec54cf178000c

One way to fix this: is to supply a maxHeight to the scroll view like component, or to the parent rendering it. This limits the height for the yoga layout calculations.


It probably comes from this commit, no? https://github.com/gorhom/react-native-bottom-sheet/commit/53974786a18aceab1cc15def1b29c94ef93002e3 - hope it helps 🙏

I also saw some other kind of bugs with that commit's changes. In general it seems like mixing flex and absolute layout can bring yoga into a position where it calculates wrong values.

hannojg avatar Jun 18 '25 13:06 hannojg

+1

ABertaud avatar Jul 01 '25 13:07 ABertaud

Same here. Though the issue is specific to Android in my case.

augini avatar Jul 04 '25 14:07 augini

Same issue for me.. Anyone can help me here.

Ravinder-webonise avatar Jul 11 '25 07:07 Ravinder-webonise

Same issue here

konstmar-ion avatar Jul 11 '25 15:07 konstmar-ion

Any updates?

Yurii-Lutsyk avatar Jul 14 '25 13:07 Yurii-Lutsyk

Any updates?

Downgrade to "@gorhom/bottom-sheet": "4.6.4" worked for me and use the FlatList that comes with react-native-gesture-handler

import { FlatList } from "react-native-gesture-handler";

Remove BottomSheetView if it's been used as it's not neccessary in this version

scalablecodes avatar Jul 24 '25 19:07 scalablecodes

remove GestureDetector and Gesture

"@gorhom/bottom-sheet": "^5.1.1"

previous code

// *Library Imports import React from 'react'; import { View, StyleSheet, FlatList } from 'react-native'; import { Text } from 'react-native-paper'; import Feather from 'react-native-vector-icons/Feather'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { useTranslation } from 'react-i18next';

// *Local IMports import { screenHeight } from '../../config/dimensions';

export default SectionWrapper = ({ children, data = [], renderItem, showAction = false, onPressAction = () => { }, horizontal = true, title = "", refresh, ...props }) => {

const nativeGesture = Gesture.Native();
const { t } = useTranslation();

return (
    <View>
        {title &&
            <View style={styles.Header} >
                <Text variant={'titleMedium'} style={{ fontFamily: 'Poppins-Regular' }}>{t(title)}</Text>
                {showAction && <Feather name={'arrow-right'} onPress={onPressAction} size={20} />}
            </View>
        }
        <GestureDetector gesture={nativeGesture}>
            <FlatList
                data={data}
                renderItem={renderItem}
                horizontal={horizontal}
                showsHorizontalScrollIndicator={false}
                showsVerticalScrollIndicator={false}
                keyExtractor={(item, index) => item?.id?.toString?.() || index.toString()}
                {...props}
                onRefresh={refresh}
                refreshing={false}
                initialNumToRender={10}
                maxToRenderPerBatch={5}
                windowSize={10}
                removeClippedSubviews={true}
                getItemLayout={props.getItemLayout}
            />
        </GestureDetector>
    </View>
);

};

const styles = StyleSheet.create({ Header: { width: '100%', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 0.015 * screenHeight, marginLeft: 0.01 * screenHeight, elevation: 4 } })

updated code

// *Library Imports import React from 'react'; import { View, StyleSheet } from 'react-native'; import { FlatList } from 'react-native-gesture-handler'; import { Text } from 'react-native-paper'; import Feather from 'react-native-vector-icons/Feather'; import { useTranslation } from 'react-i18next';

// *Local IMports import { screenHeight } from '../../config/dimensions';

export default SectionWrapper = ({ children, data = [], renderItem, showAction = false, onPressAction = () => { }, horizontal = true, title = "", refresh, ...props }) => {

const { t } = useTranslation();

return (
    <View>
        {title &&
            <View style={styles.Header} >
                <Text variant={'titleMedium'} style={{ fontFamily: 'Poppins-Regular' }}>{t(title)}</Text>
                {showAction && <Feather name={'arrow-right'} onPress={onPressAction} size={20} />}
            </View>
        }
        <FlatList
            data={data}
            renderItem={renderItem}
            horizontal={horizontal}
            showsHorizontalScrollIndicator={false}
            showsVerticalScrollIndicator={false}
            keyExtractor={(item, index) => item?.id?.toString?.() || index.toString()}
            {...props}
            onRefresh={refresh}
            refreshing={false}
            initialNumToRender={10}
            maxToRenderPerBatch={5}
            windowSize={10}
            removeClippedSubviews={true}
            getItemLayout={props.getItemLayout}
            simultaneousHandlers={props.simultaneousHandlers}
            waitFor={props.waitFor}
        />
    </View>
);

};

const styles = StyleSheet.create({ Header: { width: '100%', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 0.015 * screenHeight, marginLeft: 0.01 * screenHeight, elevation: 4 } })

GowthamResbee avatar Jul 26 '25 06:07 GowthamResbee

Do you confirm this is not fixed in 5.1.8 please? Thanks 🙌

michaelvitello avatar Jul 28 '25 07:07 michaelvitello

I have the same problem, using FlashList and FlatList, only using ScrollView and then mapping over the items was I able to solve the problem, I know mapping over items in react-native is bad, does anyone have a better solution?

TwickE avatar Aug 05 '25 15:08 TwickE

I updated to 5.1.8 and I seem to have the same issue.

Here is what I have noticed though. I have a FlashList in a BottomSheetView in a BottomSheetModal.

In development:

  1. Opening the BottomSheetModal
  2. You can't scroll
  3. Replacing the BottomSheetView with a plain react-native <View> & hot reloading
  4. You can scroll

However, if you keep using a plain View instead of the BottomSheetView, then the BottomSheetModal doesn't open at all...

Here's my ugly hack:

  const content = <BottomSheetFlashList
    estimatedItemSize={ESTIMATED_LIST_HEIGHT}
    showsVerticalScrollIndicator={false}
    data={[0]}
    renderItem={() => <FlashList 
      scrollEnabled={false}
      {...otherFlashListProps} />
    }
  />

  const [isMounted, setMounted] = useState(false)
  return (
    isMounted
      ? <View style={{ flex: 1 }}>
        {content}
      </View>
      : <BottomSheetView style={{ flex: 1 }} onLayout={() => {
        setMounted(true)
      }}>
        {content}
      </BottomSheetView>
  )

ThierryVC avatar Aug 08 '25 06:08 ThierryVC

I'm using BottomSheetScrollView and encountered this issue.

Wrapping it with <NativeViewGestureHandler disallowInterruption={true}> is fixing the issue.

I know is deprecated, but, using <GestureDetector gesture={nativeGesture}> is not working.

jbcrestot avatar Aug 22 '25 15:08 jbcrestot

I use version 5.2.5, The flashlist example doesn't work: https://gorhom.dev/react-native-bottom-sheet/components/bottomsheetflashlist Instead, I use React Native Bottom Sheet Modal. The code below with BottomSheetFlashList works for me:

import {
  BottomSheetFlashList,
  BottomSheetModal,
  BottomSheetModalProvider,
} from "@gorhom/bottom-sheet";
import React, { useCallback, useMemo, useRef } from "react";
import { Text, TouchableOpacity, View } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";

const Playground = () => {
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);
  const renderItem = useCallback(({ item }) => {
    return (
      <View key={item}>
        <Text>{item}</Text>
      </View>
    );
  }, []);

  const data = useMemo(
    () =>
      Array(1000)
        .fill(0)
        .map((_, index) => `index-${index}`),
    []
  );

  const handleLocationBoxOnPress = () => {
    bottomSheetModalRef.current?.present();
    bottomSheetModalRef.current?.snapToIndex(1);
  };

  return (
    <GestureHandlerRootView>
      <TouchableOpacity onPress={handleLocationBoxOnPress}>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
      </TouchableOpacity>
      <BottomSheetModalProvider>
        <BottomSheetModal
          ref={bottomSheetModalRef}
          index={1}
          snapPoints={["50%", "100%"]}
          enableDynamicSizing={false}
          enableDismissOnClose={true}
          enableOverDrag={false}
          overDragResistanceFactor={100}
        >
          <BottomSheetFlashList
            data={data}
            keyExtractor={(item) => item}
            renderItem={renderItem}
            keyboardShouldPersistTaps="handled"
          />
        </BottomSheetModal>
      </BottomSheetModalProvider>
    </GestureHandlerRootView>
  );
};

export default Playground;

or you may use the useBottomSheetScrollableCreator, still works for me:

import {
  BottomSheetFlashList,
  BottomSheetModal,
  BottomSheetModalProvider,
  useBottomSheetScrollableCreator,
} from "@gorhom/bottom-sheet";
import { FlashList } from "@shopify/flash-list";
import React, { useCallback, useMemo, useRef } from "react";
import { Text, TouchableOpacity, View } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";

const Playground = () => {
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);
  const renderItem = useCallback(({ item }) => {
    return (
      <View key={item}>
        <Text>{item}</Text>
      </View>
    );
  }, []);

  const data = useMemo(
    () =>
      Array(1000)
        .fill(0)
        .map((_, index) => `index-${index}`),
    []
  );

  const handleLocationBoxOnPress = () => {
    bottomSheetModalRef.current?.present();
    bottomSheetModalRef.current?.snapToIndex(1);
  };

  const BottomSheetScrollable = useBottomSheetScrollableCreator();

  return (
    <GestureHandlerRootView>
      <TouchableOpacity onPress={handleLocationBoxOnPress}>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
        <Text>Click Me!</Text>
      </TouchableOpacity>
      <BottomSheetModalProvider>
        <BottomSheetModal
          ref={bottomSheetModalRef}
          index={1}
          snapPoints={["50%", "90%"]}
          enableDynamicSizing={false}
          enableDismissOnClose={true}
          enableOverDrag={false}
          overDragResistanceFactor={100}
        >
          <FlashList
            data={data}
            keyExtractor={(item) => item}
            renderItem={renderItem}
            keyboardShouldPersistTaps="handled"
            renderScrollComponent={BottomSheetScrollable}
          />
        </BottomSheetModal>
      </BottomSheetModalProvider>
    </GestureHandlerRootView>
  );
};

export default Playground;

willytylee avatar Sep 05 '25 07:09 willytylee

@gorhom any update on this?

sergeyzwezdin avatar Sep 08 '25 04:09 sergeyzwezdin

Same issue in v5.2.6 I have tried using useBottomSheetScrollableCreator() but it does not work

@gorhom Any workaround on this?

rdnsan avatar Sep 09 '25 11:09 rdnsan

In my case scroll didn't work because the BottomSheetFlashList was wrapped into BottomSheetView Check the order of components The true order is

<GestureHandlerRootView style={StyleSheet.absoluteFill}>
   <BottomSheet
      ref={bsRef}
      enablePanDownToClose={true}
      enableOverDrag={false}
      keyboardInputMode={'adjustNothing'}
   >
      <BottomSheetFlashList 
            contentContainerStyle={styles.contentContainer}
            data={data}
      />
   </BottomSheet>
</GestureHandlerRootView>

Also BottomSheetFlashList's contentContainerStyle mustn't contain style flex: 1

vovka-s avatar Sep 26 '25 12:09 vovka-s

In my case scroll didn't work because the BottomSheetFlashList was wrapped into BottomSheetView Check the order of components The true order is

<GestureHandlerRootView style={StyleSheet.absoluteFill}>
   <BottomSheet
      ref={bsRef}
      enablePanDownToClose={true}
      enableOverDrag={false}
      keyboardInputMode={'adjustNothing'}
   >
      <BottomSheetFlashList 
            contentContainerStyle={styles.contentContainer}
            data={data}
      />
   </BottomSheet>
</GestureHandlerRootView>

Also BottomSheetFlashList's contentContainerStyle mustn't contain style flex: 1

Thank you. After removing BottomSheetView, I can scroll the Flatlist again

ddikodroid avatar Sep 30 '25 09:09 ddikodroid

In my case scroll didn't work because the BottomSheetFlashList was wrapped into BottomSheetView Check the order of components The true order is

<GestureHandlerRootView style={StyleSheet.absoluteFill}>
   <BottomSheet
      ref={bsRef}
      enablePanDownToClose={true}
      enableOverDrag={false}
      keyboardInputMode={'adjustNothing'}
   >
      <BottomSheetFlashList 
            contentContainerStyle={styles.contentContainer}
            data={data}
      />
   </BottomSheet>
</GestureHandlerRootView>

Also BottomSheetFlashList's contentContainerStyle mustn't contain style flex: 1

I can confirm that this solution solves the problem, but what if you still want a BottomSheetView with a FlashList below it?

melek-hedhili avatar Oct 01 '25 10:10 melek-hedhili

In my case scroll didn't work because the BottomSheetFlashList was wrapped into BottomSheetView Check the order of components The true order is

<GestureHandlerRootView style={StyleSheet.absoluteFill}>
   <BottomSheet
      ref={bsRef}
      enablePanDownToClose={true}
      enableOverDrag={false}
      keyboardInputMode={'adjustNothing'}
   >
      <BottomSheetFlashList 
            contentContainerStyle={styles.contentContainer}
            data={data}
      />
   </BottomSheet>
</GestureHandlerRootView>

Also BottomSheetFlashList's contentContainerStyle mustn't contain style flex: 1

I can confirm that this solution solves the problem, but what if you still want a BottomSheetView with a FlashList below it?

I have one component with such structure:

<BottomSheet ...>
    <View ... />   // <--- usual react native's view
    <BottomSheetFlashList ... />
</BottomSheet>

It works fine

vovka-s avatar Oct 02 '25 13:10 vovka-s

4 months without maintainer response. Abandoned? 🤔

Frexuz avatar Oct 08 '25 08:10 Frexuz

4 months without maintainer response. Abandoned? 🤔

There have been releases since then, could you double check if the bug still exists in the latest version? An up-to-date minimal reproduction would be very useful

AlexanderHott avatar Oct 15 '25 02:10 AlexanderHott

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] avatar Nov 14 '25 09:11 github-actions[bot]

The issue is still persist

Pjexaf avatar Nov 14 '25 16:11 Pjexaf