There are three main strategies:
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.
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 popularreact-native-safe-area-context
library for this since it has Android support as well.
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.
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 👋