What are the differences between different implementations of SafeAreaView?

15.9k Views Asked by At

A component called SafeAreaView is exported by react-native, react-navigation, react-native-safe-area-context and react-native-safe-area-view.

What are the differences and which one should I use in which cases?

3

There are 3 best solutions below

3
On BEST ANSWER

Overview

Except for the one in react-native they build on top of one another. All the others instruct that you need to wrap your whole app inside a SafeAreaProvider component.

I dug into the source code a bit and this is my deductions:

react-native

The default implementation provided with React Native. Should work for most cases but doesn't e.g. provide inset amounts programmatically.

react-native-safe-area-context

Provides detailed, retrievable inset information and a rather bare-bones implementation of SafeAreaView.

react-native-safe-area-view

Written on top of react-native-safe-area-context, it re-exports SafeAreaProvider and various other methods, but provides a more complex/fancy implementation of SafeAreaView that uses Animated.View. Adds properties such as forceInset to avoid jankiness in some cases due to layout updates. Implemented by the React Navigation team.

@react-navigation/native (v5) and react-navigation (v4)

Re-exports SafeAreaView from react-native-safe-area-view for convenience and is functionally equivalent.

Which one to use?

  1. If you don't use React Navigation and don't have special needs, use SafeAreaView from react-native. It's provided by default and works.
  2. If you don't use React Navigation but need more functionality, use react-native-safe-area-context or react-native-safe-area-view depending on your needs.
  3. If you're using React Navigation, use the one from @react-navigation/native (v5) / react-navigation (v4) or react-native-safe-area-view. It just may work better with React Navigation. Both are equivalent, choose one and use it consistently.

I recommend adding an ESLint no-restricted-imports rule that forbids accidentally importing SafeAreaView from any other location than the one you chose to use.

Example rule allowing import only from from react-navigation:

'no-restricted-imports': [
  'error',
  {
    paths: [
      {
        name: 'react-native',
        importNames: ['SafeAreaView'],
        message: 'Import SafeAreaView from react-navigation instead',
      },
      {
        name: 'react-native-safe-area-context',
        importNames: ['SafeAreaView'],
        message: 'Import SafeAreaView from react-navigation instead',
      },
      {
        name: 'react-native-safe-area-view',
        importNames: ['SafeAreaView'],
        message: 'Import SafeAreaView from react-navigation instead',
      },
    ],
  },
],
0
On

Just some additional information to complement/update @Sampo 's answer:

If you are using react-navigation v5.x, note that they do not recommend to use their own implementation of SafeAreaView, but instead to use react-native-safe-area-context:

While React Native exports a SafeAreaView component, it has some inherent issues, i.e. if a screen containing safe area is animating, it causes jumpy behavior. In addition, this component only supports iOS 10+ with no support for older iOS versions or Android. We recommend to use the react-native-safe-area-context library to handle safe areas in a more reliable way.

Source: https://reactnavigation.org/docs/handling-safe-area/

0
On

Adding another updated answer. Based on the the v6.x React Navigation docs, it is recommended to avoid using any of the implementations of the SafeAreaView component, but rather to use the useSafeAreaInsets hook when needed.

While React Native exports a SafeAreaView component, this component only supports iOS 10+ with no support for older iOS versions or Android. In addition, it also has some issues, i.e. if a screen containing safe area is animating, it causes jumpy behavior. So we recommend to use the useSafeAreaInsets hook from the react-native-safe-area-context library to handle safe areas in a more reliable way.

Note: The react-native-safe-area-context library also exports a SafeAreaView component. While it works on Android, it also has the same issues related to jumpy behavior when animating. So we recommend always using the useSafeAreaInsets hook instead and avoid using the SafeAreaView component.

Source: https://reactnavigation.org/docs/handling-safe-area