Nitish Sharma I am a mobile and web developer proficient in React, React Native, and other libraries. I am currently employed as a React Native developer.

Managing orientation changes in React Native apps

4 min read 1218 111

Managing Orientation Changes in React Native Apps

Screen orientation refers to how a device is held or positioned, typically about its vertical and horizontal axes. Screen orientation is important because it determines how a device’s screen is displayed and how users can interact with it.

For example, a device in portrait orientation will display the screen vertically, while a device in landscape orientation will display the screen horizontally. In this article, we will explore lock orientation in modern React Native applications and how to ensure that apps can only be displayed in a certain screen orientation.

Jump ahead:

Installing the expo-screen-orientation package

The expo-screen-orientation package is built by the Expo team. It includes all the tools to manage the screen orientation of a device, including fetching the current orientation, changing the orientation, and locking the screen orientation to a specific state.

To use the expo-screen-orientation, you need to install it in your React Native project by using the following commands:

$ yarn add expo-screen-orientation

$ npm install --save expo-screen-orientation
$ npx expo install expo-screen-orientation

Getting the current screen orientation

To get the current orientation of a screen in a React Native app, use the Expo-designed ScreenOrientation API, which provides information about the device’s screen orientation. You can use the getOrientationAsync property to get the current orientation of the screen, which will return an integer as its value, as shown below:

Orientation.Unknown = 0
Orientation.PORTRAIT_UP = 1
Orientation.PORTRAIT_DOWN = 2
Orientation.LANDSCAPE_LEFT = 3
Orientation.LANDSCAPE_RIGHT = 4

Here is a code snippet to fetch the current screen orientation:

const checkOrientation = async () => {
    const orientation = await ScreenOrientation.getOrientationAsync();
    console.log("orientation", orientation);
};

Listening to screen orientation updates

To check for updates to the screen orientation, use the addOrientationChangeListener method from the ScreenOrientation API. This will pass a callback function that will be called whenever the orientation changes. This callback function will receive an event object containing information about the new orientation, which you can use to update your app’s UI or handle the orientation change in another way.

Here is an example of how you can use these APIs to handle orientation changes in your app:

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
import * as ScreenOrientation from "expo-screen-orientation";
import { useEffect, useState } from "react";
export default function App() {
  const [orientation, setOrientation] = useState(null);
  useEffect(() => {
    checkOrientation();
    const subscription = ScreenOrientation.addOrientationChangeListener(
      handleOrientationChange
    );
    return () => {
      ScreenOrientation.removeOrientationChangeListeners(subscription);
    };
  }, []);
  const checkOrientation = async () => {
    const orientation = await ScreenOrientation.getOrientationAsync();
    setOrientation(orientation);
  };
  const handleOrientationChange = (o) => {
    setOrientation(o.orientationInfo.orientation);
  };
  console.log(orientation);
  return (
    <View style={styles.container}>
      <Text>ORIENTATION: {orientation}</Text>
      <StatusBar style="auto" />
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

Here’s what the portrait and landscape screen orientations look like:
React Native App in Portrait ModeReact Native App in Landscape Mode

In this example, we use the ScreenOrientation API to get the screen’s current orientation and to listen for orientation changes. When the orientation changes, we update the orientation state variable using the setOrientation Hook.

Then, we use this state variable to display the current orientation in the log. The response of the listener is in the form of the object as shown below:

{
   "orientationInfo":{
      "horizontalSizeClass":1,
      "orientation":4,
      "verticalSizeClass":1
   },
   "orientationLock":0
}

We also use the ScreenOrientation API to lock the screen to portrait orientation, which means that the user will not be able to rotate the screen to landscape orientation. This can be useful if you want to prevent the app from being displayed in a landscape orientation or to ensure that the app always displays in a specific orientation.

How to lock the screen orientation

To disable orientation changes or set a single orientation for your React Native app, you can use the ScreenOrientation API. This API provides methods for controlling the orientation of the screen.

You can use the lockAsync method to lock the screen in a specific orientation or the unlockAsync method to allow the screen to be rotated to any orientation.

Below is the example for locking the orientation programmatically:

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
import * as ScreenOrientation from "expo-screen-orientation";
import { useEffect, useState } from "react";
export default function App() {
  const [orientation, setOrientation] = useState(1);
  useEffect(() => {
    lockOrientation();
  }, []);
  const lockOrientation = async () => {
    await ScreenOrientation.lockAsync(
      ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT
    );
  const o = await ScreenOrientation.getOrientationAsync();
    setOrientation(o);
  };
  return (
    <View style={styles.container}>
      <Text>Locked Screen orientation: {orientation}</Text>
      <StatusBar style="auto" />
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

In bare React Native apps, we have another way to lock the screen orientations of the apps.

Android

Open the AndroidManifest.xml file and set android:screenOrientation="portrait" to lock the screen in portrait or android:screenOrientation="landscape" to lock the screen in landscape mode. Here’s what that should look like:

<activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
      android:launchMode="singleTask"
      android:windowSoftInputMode="adjustResize"
      android:exported="true"
      android:theme="@style/Theme.App.SplashScreen"
      android:screenOrientation="portrait"
    >

iOS

To manage screen orientation in iOS, open Xcode and check the orientation that you need for your app in General > Deployment Info:

React Native Screen Orientation in iOS

Example of controlling screen orientation in React Native

Now, what if one needs to update the orientation programmatically? For example, when playing a video, you would want it displayed in landscape mode for a better viewing experience for the users.

Here is an easy-to-use example to update and lock the screen orientation on button taps and clicks using expo-screen-orientation:

import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import * as ScreenOrientation from "expo-screen-orientation";
import { useEffect, useState } from "react";
export default function App() {
  const [orientation, setOrientation] = useState(null);
  useEffect(() => {
    checkOrientation();
    const subscription = ScreenOrientation.addOrientationChangeListener(
      handleOrientationChange
    );
    return () => {
      ScreenOrientation.removeOrientationChangeListeners(subscription);
    };
  }, []);
  const checkOrientation = async () => {
    const orientation = await ScreenOrientation.getOrientationAsync();
    setOrientation(orientation);
  };
  const changeOrientation = async (newOrientation) => {
    console.log("newOrientation: ", newOrientation);
    await ScreenOrientation.lockAsync(newOrientation);
  };
  const handleOrientationChange = (o) => {
    setOrientation(o.orientationInfo.orientation);
  };
  console.log(orientation);
  return (
    <View style={styles.container}>
      <Text>ORIENTATION: {orientation}</Text>
      <TouchableOpacity
        style={[styles.btn, { marginTop: 15 }]}
        onPress={() =>
          changeOrientation(ScreenOrientation.OrientationLock.PORTRAIT_UP)
        }
      >
        <Text style={styles.txt}>Tap to Portrait orientation</Text>
      </TouchableOpacity>
      <TouchableOpacity
        style={styles.btn}
        onPress={() =>
          changeOrientation(ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT)
        }
      >
        <Text style={styles.txt}>Tap to Landscape orientation</Text>
      </TouchableOpacity>
      <StatusBar style="auto" />
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  btn: {
    padding: 10,
  },
  txt: {
    fontSize: 16,
    color: "blue",
  },
});

And, voila! Below is a video clip of what we achieved with the code above:

Conclusion

In conclusion, screen orientation is an important aspect of device interaction. Expo APIs allow you to get the current orientation, listen for orientation changes, and control the screen’s orientation in your React Native apps.

These APIs help you create more engaging and user-friendly apps that adapt to different orientations and provide a consistent UX. Overall, the expo-screen-orientation package is a valuable tool for any React Native app that needs to manage screen orientation.

LogRocket: Instantly recreate issues in your React Native apps.

LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.

LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.

Start proactively monitoring your React Native apps — .

Nitish Sharma I am a mobile and web developer proficient in React, React Native, and other libraries. I am currently employed as a React Native developer.

One Reply to “Managing orientation changes in React Native apps”

  1. Would be better if you mentioned commenting out the default orientation: portrait inside app.json on iOS. If this isn’t done, then the code doesn’t work, as orientation modes don’t change.

    Suggest add to the beginning. Otherwise its a reasonably good article.

Leave a Reply