Good to know
Context inside a sheet
gorhom renders modal content next to BottomSheetModalProvider, not where the sheet was opened. useSheets() and useSheetHandle() still work inside it, but any other provider that content needs (theme, i18n, data clients, safe area) must be above BottomSheetModalProvider. That includes your navigation library's hooks: inside <SheetModal> they see whatever navigator is around the provider, if any, not the screen that opened the sheet.
The sheet component's own body, outside <SheetModal>, renders where its scope is. It can read screen-level context there and pass values down as props.
Render <SheetModal> on the first render
A sheet that renders no SheetModal, or more than one, is rejected with an error naming it.
Backdrops are opt-in
gorhom draws no backdrop unless you give it one, so a sheet like the one in Getting started has nothing behind it to tap. To dim the screen and close the sheet on a tap outside, pass gorhom's backdropComponent:
import {
BottomSheetBackdrop,
type BottomSheetBackdropProps,
} from '@gorhom/bottom-sheet';
// Defined once, outside any component, so its identity never changes.
const renderBackdrop = (props: BottomSheetBackdropProps) => (
<BottomSheetBackdrop {...props} appearsOnIndex={0} disappearsOnIndex={-1} />
);
// In the sheet:
<SheetModal backdropComponent={renderBackdrop}>{/* ... */}</SheetModal>;
Stacking sheets
A sheet's stackBehavior (a SheetModal prop) decides what happens to the sheet below when it opens: 'push' keeps it on screen, and 'replace' dismisses it, so its promise resolves undefined.
- iOS
- Android
gorhom's default, 'switch', should minimise the sheet below until the new sheet closes. In @gorhom/bottom-sheet 5.2.14 it dismisses it instead (gorhom#2685, fix pending in gorhom#2698). Until that ships, set stackBehavior="push" on sheets that open over other sheets.
Memoise snapPoints
gorhom recalculates layout whenever snapPoints changes identity. Define them at module scope, or with useMemo.
Props are a snapshot
show() captures props when it's called. To change them later, use update() or sheet.update(), or read live data from your state library inside the sheet.
Inline sheets
The library only manages modals. For a sheet that's always on screen, such as a map's results panel, render gorhom's BottomSheet in your screen as usual:
function MapScreen() {
const sheets = useSheets();
return (
<View style={{ flex: 1 }}>
{/* A managed sheet, opened above the inline one. */}
<Map onPressFilters={() => sheets.show('filters')} />
<BottomSheet snapPoints={snapPoints}>
<BottomSheetView>
<Results />
</BottomSheetView>
</BottomSheet>
</View>
);
}
It works next to a <SheetScope>, and managed sheets open above it. The library doesn't open, close or type it, and Android's back button won't close it.
A registered sheet can't use BottomSheet as its root: it must render <SheetModal>.