Use Native Modals Over JS-Based Bottom Sheets
Use Native Modals Over JS-Based Bottom Sheets
Section titled “Use Native Modals Over JS-Based Bottom Sheets”Use native <Modal> with presentationStyle="formSheet" or React Navigation
v7’s native form sheet instead of JS-based bottom sheet libraries. Native modals
have built-in gestures, accessibility, and better performance. Rely on native UI
for low-level primitives.
Incorrect (JS-based bottom sheet):
import BottomSheet from 'custom-js-bottom-sheet'
function MyScreen() { const sheetRef = useRef<BottomSheet>(null)
return ( <View style={{ flex: 1 }}> <Button onPress={() => sheetRef.current?.expand()} title='Open' /> <BottomSheet ref={sheetRef} snapPoints={['50%', '90%']}> <View> <Text>Sheet content</Text> </View> </BottomSheet> </View> )}Correct (native Modal with formSheet):
import { Modal, View, Text, Button } from 'react-native'
function MyScreen() { const [visible, setVisible] = useState(false)
return ( <View style={{ flex: 1 }}> <Button onPress={() => setVisible(true)} title='Open' /> <Modal visible={visible} presentationStyle='formSheet' animationType='slide' onRequestClose={() => setVisible(false)} > <View> <Text>Sheet content</Text> </View> </Modal> </View> )}Correct (React Navigation v7 native form sheet):
// In your navigator<Stack.Screen name='Details' component={DetailsScreen} options={{ presentation: 'formSheet', sheetAllowedDetents: 'fitToContents', }}/>Native modals provide swipe-to-dismiss, proper keyboard avoidance, and accessibility out of the box.