Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between different implementations of SafeAreaView?

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?

like image 480
Sampo Avatar asked May 19 '20 09:05

Sampo


2 Answers

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',
      },
    ],
  },
],
like image 67
Sampo Avatar answered Nov 12 '22 23:11

Sampo


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/

like image 31
vaz Avatar answered Nov 12 '22 23:11

vaz