1500+ ready React Native mobile app screens

Affiliates
Blog

How to Make a Bottom Sheet in React Native Without Breaking on Keyboard Input

Photo by Ahmed ؜ on Pexels

How to Make a Bottom Sheet in React Native Without Breaking on Keyboard Input

To create a bottom sheet in React Native that works well with keyboard input, use the @gorhom/bottom-sheet library. This library allows the bottom sheet to resize based on the presence of the keyboard, providing a smooth user experience without breaking the layout.

Why Use Gorhom’s Bottom Sheet?

Gorhom's Bottom Sheet is specifically designed for React Native and includes features that handle gestures, animations, and keyboard awareness. It effectively creates interactive and responsive modals that integrate seamlessly into your app while avoiding common pitfalls, especially with forms.

How Do I Install Gorhom Bottom Sheet?

To install the Gorhom Bottom Sheet, run the following command in your project directory:

npm install @gorhom/bottom-sheet

Make sure to have the requisite dependency versions for React Native and react-native-reanimated, as it depends on these libraries:

npm install react-native-reanimated

You should also ensure you are using a decent version of React Native (0.60 and above) for optimal compatibility.

What Props Do I Need for a Form Inside a Bottom Sheet?

Key props for effective usage of a bottom sheet with a text input include enablePanDownToClose, keyboardDismissMode, and snapPoints. Here’s a basic setup with these props in mind:

import React, { useRef, useCallback } from 'react';
import { View, TextInput, Button } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';

const MyBottomSheet = () => {
  const bottomSheetRef = useRef(null);
  const snapPoints = ['50%', '90%'];

  const handleClose = useCallback(() => {
    bottomSheetRef.current?.close();
  }, []);

  return (
    <BottomSheet
      ref={bottomSheetRef}
      index={0}
      snapPoints={snapPoints}
      enablePanDownToClose={true}
      keyboardDismissMode="on-drag"
    >
      <View style={{ padding: 16 }}>
        <TextInput placeholder="Enter text here" style={{ height: 40, borderColor: 'gray', borderWidth: 1 }} />
        <Button title="Close" onPress={handleClose} />
      </View>
    </BottomSheet>
  );
};

How Do I Handle Keyboard Events?

When designing a bottom sheet that accommodates text inputs, you need to ensure the bottom sheet responds correctly to keyboard visibility. Set keyboardDismissMode to on-drag as done above, allowing the sheet to dismiss when the user drags downwards. This can enhance usability for forms.

However, you might also want to listen to keyboard events to adjust the height of the bottom sheet dynamically:

import { Keyboard, StyleSheet } from 'react-native';

Keyboard.addListener('keyboardDidShow', () => {
  bottomSheetRef.current?.snapToIndex(1); // Adjust snap point for keyboard
});

Keyboard.addListener('keyboardDidHide', () => {
  bottomSheetRef.current?.snapToIndex(0); // Collapse when keyboard hides
});

Remember to remove these listeners when unmounting your component to avoid memory leaks.

Why Does My Bottom Sheet Lag with Keyboard Input?

If you're experiencing lag, it may be due to performance issues with mid-range Android devices. Optimize your component by avoiding heavy calculations or applying heavy animations when the keyboard is displayed. Use native driver for animations through react-native-reanimated where possible:

const translateY = useSharedValue(0);
 
useEffect(() => {
  translateY.value = withSpring(keyboardVisible ? -50 : 0);
}, [keyboardVisible]);

How Do I Customize the Appearance of the Bottom Sheet?

Customizing the bottom sheet involves styling through props such as backgroundStyle and applying your own View components inside the sheet. Here’s an example of changing the background color:

<BottomSheet
  ...
  backgroundStyle={{ backgroundColor: 'white' }}
>
  <View style={styles.content}>
  {/* Your content here */}
  </View>
</BottomSheet>

How Can I Add More Complex Animations Inside the Bottom Sheet?

For advanced animations, leverage react-native-reanimated to create seamless transitions. You might want to animate the opacity or scale of elements inside the bottom sheet to enhance user experience:

const opacity = useSharedValue(0);

useEffect(() => {
  opacity.value = withTiming(1, { duration: 300 });
}, []);

return (
  <Animated.View style={{ opacity: opacity.value }}>
    {/* Your animated content */}
  </Animated.View>
);

What’s Next?

You can explore more complex implementations and user interfaces for your projects. For users needing boilerplate setups along with animated flows, check out Clevens for ready-made designs that you can complete with a simple copy-paste.