There are three main strategies:

  1. Using the SafeAreaView
  2. Using an invisible component that occupies the space
  3. Getting the inset values and applying it directly (two ways to get the values. Either going native, or using a lib)

Intro:

If you try searching for "handling the safe area on react-native" you will be face with thousands of articles basically telling you to do the same thing: Use the safe-area-view and all your problems are solved.

That might solve your problem for your demo app, but is far from solving real-life-production use-cases.

For real life scenarios you need a combination of approaches to handle different design possibilities.

Here I will show three that, in combination, cover most of the cases you will face.

Using the SafeAreaView

Let's get this one out of the way first. If you have a view and you want it to completely avoid the notch on the top and handle bar in the bottom, you can just wrap this with a SafeAreaView and call it a day.

Important: here I am not suggesting the React-native implementation of the SafeAreaView since it only supports iOS. You are better of, using the very good and popular react-native-safe-area-context library for this since it has Android support as well.

Using a spacer element

Now, imagine that you have a view that you want to extend to the whole screen and you have a button at the bottom that you want to have enough space from the bottom handle so the user doesn't press either by mistake.

Wrapping it with a SafeAreaView will not be sufficient. That would add the insets and prevent background from going all the way behind.

You could potentially have the SafeAreaView inside the parent view but that would cut on your flexibility, so let's stick with this scenario for illustration purposes.

In this case you can user a spacer component. Again, we can leverage the react-native-safe-area-context library for that. It provides a hook where you can get all the insets from the device. With the insets values, you can then generate a component that takes up that space. See example below:

const SafeSpace: React.FC<SafeSpaceProps> = (props) => {
  const { type } = props
  const { bottom, top } = useSafeAreaInsets()

  return (
    <View
      style={{
        width: '100%',
        height: Platform.select({
          ios: type === 'TOP' ? top : bottom,
          android: minimum ?? 16,
        }),
      }}
    />
  )

With this component in place, you can then use it to space your button from the bottom of the screen without having to affect the background view component, allowing it to extend fully.

Getting the insets from Native

Another option, which I will not get into lots of details here, is to get the values directly from the Native side of your application.

This is specially useful if you want to use the specific values for styling of for creating helping functions to be executed outside the context of your components, where you cannot directly use hooks.

I will save the implementation details for a future post with a step-by-step about how to expose these kind of functionalities from the native side on the current architecture.


Hit me up on Twitter, say hi and disagree 👋