Skip to main content

Imperative vs Portal API

This library provides two approaches for working with bottom sheets. Both are equally capable - choose based on your preferences and use case.

Overview

Imperative APIPortal API
StyleFully imperativeDeclarative definition, imperative control
HookuseBottomSheetManageruseBottomSheetControl
OpenopenBottomSheet(<Component />)open()
React ContextFrom BottomSheetHost locationFrom definition site
Sheet definitionAt the call siteAnywhere in the component tree

Imperative API

Open sheets directly by passing JSX:

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

function MyComponent() {
const { openBottomSheet } = useBottomSheetManager();

const handleOpen = () => {
openBottomSheet(<MySheet />, {
mode: 'push',
scaleBackground: true,
});
};

return <Button title="Open" onPress={handleOpen} />;
}

Characteristics:

  • Sheet content is passed directly to openBottomSheet()
  • Content is stored in Zustand and rendered in BottomSheetHost
  • Sheets have access to context that wraps BottomSheetHost, not the call site
Context with Imperative API

If you need context access with Imperative API, wrap BottomSheetHost with your providers:

<ThemeProvider>
<AuthProvider>
<BottomSheetHost /> {/* Sheets rendered here have access to Theme and Auth */}
</AuthProvider>
</ThemeProvider>

Sheets will have access to these contexts, but not to context from where openBottomSheet() is called.

Portal API

Declare sheets in your component tree, control them by ID:

import {
BottomSheetPortal,
useBottomSheetControl,
} from 'react-native-bottom-sheet-stack';

function MyComponent() {
const { open } = useBottomSheetControl('my-sheet');

return (
<View>
<BottomSheetPortal id="my-sheet">
<MySheet />
</BottomSheetPortal>

<Button title="Open" onPress={() => open({ scaleBackground: true })} />
</View>
);
}

Characteristics:

  • Sheet is declared as JSX in your component tree
  • Content stays in your React tree (via react-native-teleport)
  • React context (theme, auth, i18n, navigation) is preserved
  • Can define sheet in one place and open from anywhere within the same provider

When to Choose

Imperative API

  • You prefer a fully imperative, inline approach
  • Context preservation is not needed
  • You want to define sheets dynamically at the call site

Portal API

  • You need React context inside the sheet (theme, auth, i18n, navigation)
  • You want to define a sheet once and open it from multiple places
  • You prefer declarative sheet definitions in JSX

Both APIs Support

  • All navigation modes (push, switch, replace)
  • Scale animation (scaleBackground: true)
  • Stacking multiple sheets
  • Type-safe params