Skip to main content

Hooks

Hooks are divided into two categories based on where they can be used:

HookWhere to usePurpose
useBottomSheetManagerAnywhereOpen/close sheets imperatively
useBottomSheetControlAnywhereControl portal-based sheets
useBottomSheetStatusAnywhereSubscribe to sheet status by ID
useBottomSheetContextInside sheet onlyAccess current sheet's state and params
useOnBeforeCloseInside sheet onlyIntercept close and optionally prevent it

useBottomSheetManager

Main hook for opening and managing bottom sheets imperatively.

const { open, close, closeAll, clear } = useBottomSheetManager();

Returns

PropertyTypeDescription
open(content, options?) => stringOpens a bottom sheet and returns its ID
close(id: string) => voidCloses a specific sheet by ID
closeAll(options?) => Promise<void>Closes all sheets with cascading animation
clear() => voidRemoves all sheets immediately (no animation)

closeAll Options

Closes all sheets in the group from top to bottom with a staggered animation. Respects useOnBeforeClose interceptors — if one blocks, the cascade stops.

// Default stagger (100ms between each close)
await closeAll();

// Custom stagger
await closeAll({ stagger: 200 });

// No stagger (all close at once)
await closeAll({ stagger: 0 });
OptionTypeDefaultDescription
staggernumber100Delay in ms between each cascading close

open Options

open(<MySheet />, {
id: 'my-sheet-id', // Custom ID (optional)
groupId: 'my-group', // Custom group (optional)
mode: 'push', // 'push' | 'switch' | 'replace'
scaleBackground: true, // Enable scale animation
});
OptionTypeDefaultDescription
idstringrandomCustom sheet ID
groupIdstringcontext or 'default'Group ID for the sheet
modeOpenMode'push'Navigation mode
scaleBackgroundbooleanfalseEnable background scaling

Deprecated Aliases

DeprecatedUse Instead
openBottomSheetopen
clearAllclear

useBottomSheetContext

Access the current sheet's state, params, and close function.

Inside Sheet Only

This hook can only be used inside a sheet adapter component (e.g. GorhomSheetAdapter, CustomModalAdapter). It reads from React context - no ID parameter needed.

// Basic usage
const { id, params, close, forceClose } = useBottomSheetContext();

// With typed params (for portal sheets)
const { params, close } = useBottomSheetContext<'my-sheet'>();

Generic Parameter

Pass the portal sheet ID as a generic to get typed params:

// If registry defines: 'user-sheet': { userId: string }
const { params } = useBottomSheetContext<'user-sheet'>();
console.log(params.userId); // type-safe: string

Returns

PropertyTypeDescription
idstringCurrent sheet's ID
paramsBottomSheetPortalParams<T> or unknownType-safe params when generic provided
close() => voidCloses this sheet (respects useOnBeforeClose)
forceClose() => voidCloses this sheet immediately, bypassing any useOnBeforeClose interceptor

Deprecated Aliases

DeprecatedUse Instead
useBottomSheetStateuseBottomSheetContext
closeBottomSheetclose

useBottomSheetControl

Control portal-based sheets from anywhere in your app. Pass the sheet ID to identify which sheet to control.

No Re-renders

Returns only methods - no state subscriptions. Use useBottomSheetStatus separately if you need to react to status changes.

const { open, close, closeAll, updateParams, resetParams } = useBottomSheetControl('my-sheet');

Parameters

ParameterTypeDescription
idBottomSheetPortalIdThe portal sheet ID to control

Returns

PropertyTypeDescription
open(options?) => voidOpens the sheet
close() => voidCloses the sheet (respects useOnBeforeClose)
closeAll(options?) => Promise<void>Closes all sheets with cascading animation
updateParams(params) => voidUpdates the sheet's params
resetParams() => voidResets params to undefined

open Options

// Sheet without params (registry: 'simple-sheet': true)
open();
open({ scaleBackground: true });

// Sheet with params (registry: 'user-sheet': { userId: string })
open({
mode: 'push',
scaleBackground: true,
params: { userId: '123' } // Required when params defined in registry
});
OptionTypeDefaultDescription
modeOpenMode'push'Navigation mode
scaleBackgroundbooleanfalseEnable background scaling
paramsBottomSheetPortalParams<T>-Type-safe params

useBottomSheetStatus

Subscribe to any sheet's status from anywhere in your app. Pass the sheet ID to identify which sheet to observe.

Works with All Sheet Types

This hook accepts any string ID, so it works with portal sheets, persistent sheets, and inline sheets (using the ID returned from useBottomSheetManager().open()).

// Portal/persistent sheet
const { status, isOpen } = useBottomSheetStatus('my-sheet');

// Inline sheet (using ID from open())
const { open } = useBottomSheetManager();
const sheetId = open(<MySheet />);
// ...
const { status, isOpen } = useBottomSheetStatus(sheetId);

Parameters

ParameterTypeDescription
idstringThe sheet ID to observe (portal ID or inline sheet ID)

Returns

PropertyTypeDescription
statusBottomSheetStatus | nullCurrent status or null if never opened
isOpenbooleantrue if status is 'open' or 'opening'

Status Values

StatusDescription
'opening'Sheet is animating open
'open'Sheet is fully open
'closing'Sheet is animating closed
'hidden'Sheet is hidden (switch mode)
nullSheet has not been opened

Example: Separating Control and Status

function MyComponent() {
// No re-renders from this hook
const { open, close } = useBottomSheetControl('my-sheet');

return <Button onPress={() => open()} title="Open" />;
}

function StatusIndicator() {
// Only this component re-renders on status changes
const { isOpen } = useBottomSheetStatus('my-sheet');

return <Text>{isOpen ? 'Sheet is open' : 'Sheet is closed'}</Text>;
}

useOnBeforeClose

Registers an interceptor that runs before the sheet closes. Receives onConfirm and onCancel callbacks to call when the user makes a decision.

Inside Sheet Only

This hook can only be used inside a sheet adapter component. It reads from React context — no ID parameter needed.

import { useOnBeforeClose } from 'react-native-bottom-sheet-stack';

function MySheet() {
const [dirty, setDirty] = useState(false);

useOnBeforeClose(({ onConfirm, onCancel }) => {
if (!dirty) {
onConfirm(); // Allow close immediately
return;
}

Alert.alert('Discard?', '', [
{ text: 'Cancel', style: 'cancel', onPress: onCancel },
{ text: 'Discard', onPress: onConfirm },
]);
});

// ...
}

Parameters

ParameterTypeDescription
callbackOnBeforeCloseCallbackFunction called before close. Call onConfirm() to allow or onCancel() to block.

Callback Signature

type OnBeforeCloseCallback = (context: {
onConfirm: () => void;
onCancel: () => void;
}) => void | boolean | Promise<boolean>;

Callback Pattern (Recommended):

  • Call onConfirm() — close proceeds
  • Call onCancel() — close is cancelled
  • Perfect for Alert.alert and closeAll() integration

Backward Compatible Patterns:

  • Return true — close proceeds normally
  • Return false — close is cancelled
  • Return Promise<boolean> — async confirmation supported
  • If the promise rejects — close is cancelled for safety

Behavior

When active, the hook:

  1. Sets preventDismiss on the sheet so adapters block native dismiss gestures (swipe, pan-to-close)
  2. Intercepts all close paths: close(), backdrop tap, back button, closeAll()
  3. With callback pattern, closeAll() waits for user decision before continuing cascade

Use forceClose() from useBottomSheetContext to bypass the interceptor entirely.

See Close Interception for detailed guide and examples.