Improve mobile UI with React Native safe-area-context

When building a mobile application, a developer must repeatedly ensure that the content is rendered correctly on different types of screens. Time-consuming and error-prone, we can simplify this process using tools like  React Native’s safe-area-context API.

In this tutorial, we’ll use safe-area-context to position webpage content around irregular figures in a mobile application, for example, status bars, home indicators, and notches. To follow along with this tutorial, you should be familiar with React Native and React Hooks. Let’s get started!

Note: To follow along, you can check out the full codebase of the to-do list app used in this article

Mobile UI limitations

Let’s assume you’ve built the following React Native application that adds and removes items off of a to-do list:

Our to-do list app is functional and fairly easy to use. In a web view, our application wouldn’t look abnormal. However, you’ll quickly notice several problems with the mobile UI. For example, if a user tried to view the app in landscape mode, they would encounter the following error:

 

When a user turns their phone and tries to use landscape mode, our app’s header becomes partially blocked due to the mobile screen dimensions.

When adapting a web application for mobile screen dimensions, it is very common for certain elements to become blocked or distorted by mobile interface elements. Let’s improve the visual rendering of our header element using the safe-area-context API.

Getting started with safe-area-context

First, we’ll install safe-area-context in our project. Navigate to the root project of your folder and run the command below:

npm install react-native-safe-area-context

If you’re using React Native ≥v0.6.0, safe-area-context will be automatically linked to your project. However, if you’re using an earlier version of React Native, run the following command in the root folder of your project to link the library:

react-native link react-native-safe-area-context

safe-area-context uses two components to interact with React Native components, Providers and Consumers, which have a parent-child relationship. Consumers allow us to use the values that are made available by the nearest Provider.

In the safe-area-context library, only one component,SafeAreaProvider, serves as a Provider. Let’s wrap the root component of our app with the SafeAreaProvider component, which will provide the value or styles of any system element it overlaps to descendant consumers.

Add the code below to App.js:

import React from "react";
import { Text, View, StyleSheet, ScrollView, TouchableOpacity, KeyboardAvoidingView } from "react-native";
import { SafeAreaView, SafeAreaProvider } from "react-native-safe-area-context";
import Task from "./components/Tasks";

export default function App() {
  const [task, setTask] = useState();
  const [taskItems, setTaskItems] = useState([]);
  const handleAddTask = () => {
    Keyboard.dismiss();
    setTaskItems([...taskItems, task]);
    setTask(null);
  };
  const completeTask = (index) => {
    let itemsCopy = [...taskItems];
    itemsCopy.splice(index, 1);
    setTaskItems(itemsCopy);
  };
  return (
    <SafeAreaProvider>
      <ScrollView>
        <View style={styles.container}>
          <View style={styles.taskWrapper}>
            <Text style={styles.sectionTitle}>Today's Tasks</Text>

            <View style={styles.items}>
              {/* This is where the tasks will go   */}
              {taskItems.map((item, index) => {
                return (
                  <TouchableOpacity onPress={() => completeTask(index)}>
                    <Task key={index} text={item} />
                  </TouchableOpacity>
                );
              })}
            </View>
          </View>
          {/* Write a task*/}

          <KeyboardAvoidingView
            behavior={Platform.OS === "ios" ? "padding" : "height"}
            style={styles.writeTaskWrapper}
          >
            <TextInput
              style={styles.input}
              placeholder={"Write a task"}
              value={task}
              onChangeText={(text) => setTask(text)}
            />
            <TouchableOpacity onPress={() => handleAddTask()}>
              <View style={styles.addWrapper}>
                <Text style={styles.addText}>+</Text>
              </View>
            </TouchableOpacity>
          </KeyboardAvoidingView>
        </View>
      </ScrollView>
    </SafeAreaProvider>
  );
}

Next, we’ll wrap any element that we anticipate could be impacted by screen modifications in mobile devices with a Consumer component. In our case, we wrap the Text child component that contains the header of our to-do list app with SafeAreaView, the primary Consumer component in safe-area-context:

// ./App.js

import React from "react";
import { Text, View, StyleSheet, ScrollView } from "react-native";
import { SafeAreaView, SafeAreaProvider } from "react-native-safe-area-context";

export default function App() {
  return (
    <SafeAreaProvider>
      <ScrollView>
        <View style={styles.container}>

          ...

          <View style={styles.taskWrapper}>
            <SafeAreaView>
              <Text style={styles.sectionTitle}>Today's Tasks</Text>
            </SafeAreaView>
          </View>

          ...

        </View>
      </ScrollView>
    </SafeAreaProvider>
  );
}

SafeAreaView acts like a regular React Native View component, however, it includes additional padding and margins, positioning the enclosed component away from any mobile onscreen modifications.

SafeAreaView includes a prop for edges, allowing you to customize safe area insets around the edges of your component. edges takes values of top, right, bottom, and left, with all as the default.

Let’s see how our app’s header is positioned differently after adding the SafeAreaView component:

 

In the video above, our app’s header is more centralized. The extra styling provided by SafeAreaView prevents mobile screen modifications from blocking the header, regardless of the type of device or screen dimensions.

safe-area-context includes built-in testing with Jest. You can read more about testing in the docs.

Optimizing rendering with SafeAreaView

The SafeAreaView component can prevent rendering delays when a user rotates their device. Additionally, React Native uses a Provider property called initialWindowMetrics that you can use to speed up your application’s initial render. Let’s add initialWindowMetrics in App.js:

// ./App.js

import React from "react";
import { Text, View, StyleSheet, ScrollView } from "react-native";
import { SafeAreaView, SafeAreaProvider, InitialWindowMetrics } from "react-native-safe-area-context";

export default function App() {
  return (
    <SafeAreaProvider initialMetrics={initialWindowMetrics}>
      <ScrollView>
        <View style={styles.container}>

          ...

          <View style={styles.taskWrapper}>
            <SafeAreaView>
              <Text style={styles.sectionTitle}>Today's Tasks</Text>
            </SafeAreaView>
          </View>

          {/* Include TextInput and button for adding items here */}

        </View>
      </ScrollView>
    </SafeAreaProvider>
  );
}

The initialWindowsMetrics property is specified as the initialMetric prop. This property should only be used if your application’s provider doesn’t remount, or if your application isn’t making use of the React Navigation library.

Summary

Handling and managing data in mobile applications can be a challenge in comparison to web applications. However, tools like safe-area-context provide a pathway to building interfaces that easily adapt to different mobile screens, providing a uniform UX across different devices.

safe-area-context is easy to use by simply wrapping elements with the SafeAreaView component. While the default values are effective on their own, you can add custom values to padding, margin, and edges as you see fit for your application. I hope you enjoyed this tutorial!

The post Improve mobile UI with React Native safe-area-context appeared first on LogRocket Blog.

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

Improve mobile UI with React Native safe-area-context

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.