Responsive Design in React Navigation

Sep 17, 2023 ⋅ Modified: Sep 17, 2023 ⋅ 5 min read

Bilal Arslan

Hi there! I'm a full-stack developer who loves crafting web and mobile apps. When I'm not coding, I enjoy sharing my knowledge as a technical writer. Let's build something awesome together!

Introduction

In today's blog post, we will take a look at into the world of responsive design in React Native. As you know, when implementing components, we often use various UI properties such as width, height, margin, padding, radius, and fontSize. These properties define how a component looks. However, there's a challenge: every device has its unique screen resolution. For instance, the iPhone 12 has a resolution of 1170 x 2532 pixels, the Samsung S23 Ultra boasts 1440 x 3088 pixels, and the iPad Pro 12 measures 2048 x 2732 pixels. If we use the same sizes for components across all devices, our app may appear drastically different on each device, which is not the outcome we desire.

Fortunately, the solution is quite simple. All we need is a utility class to maintain consistent component ratios according to the screen resolution. Let's explore this with an example.

Creating Project

Let's set up our React Native project using Expo CLI:

npx create-expo-app react-native-responsive

Starting the Emulator:

To launch the emulator, execute the following command:

npx expo start

Implementation

To active the problem, all we need to have a utils object like this;

// ./utils/responsive.js
 
import { Dimensions } from "react-native";
 
const { width: deviceWidth, height: deviceHeight } = Dimensions.get("window");
 
const BaseWidth = 375;
 
const scale = (size) => (deviceWidth / BaseWidth) * size;
const moderateScale = (size, factor = 0.5) =>
  size + (scale(size) - size) * factor;
 
export const responsive = {
  fontSize: (size) => moderateScale(size, 1),
  number: (n) => moderateScale(n, 1),
  deviceWidth,
  deviceHeight,
};

Now, we have two functions and two properties within the responsive object:

  • fontSize: We use this when specifying font sizes.
  • number: This function covers all other pixel values within style objects.
  • deviceWidth: Represents the screen width.
  • deviceHeight: Represents the screen height.

Let's apply our responsive object within our app:

// ./App.js
 
import { Text, View, TouchableOpacity } from 'react-native';
 
import { responsive } from './utils/responsive';
 
export default function App() {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
 
      <Text style={{
        fontSize: responsive.fontSize(20),
        marginBottom: responsive.number(5)
      }}>
        React Native Space
      </Text>
 
      <Text style={{
        fontSize: responsive.fontSize(18),
        marginBottom: responsive.number(5)
      }}>
        Screen Resolution
      </Text>
 
      <Text style={{
        fontSize: responsive.fontSize(16),
        marginBottom: responsive.number(10)
      }}>
        {Math.round(responsive.deviceWidth) + ' x ' + Math.round(responsive.deviceHeight)}
      </Text>
 
      <TouchableOpacity style={{
        backgroundColor: '#1abc9c',
        justifyContent: 'center',
        alignItems: 'center',
        width: responsive.number(250),
        height: responsive.number(50),
        borderRadius: responsive.number(20),
        marginBottom: responsive.number(5)
 
      }}>
        <Text style={{
          color: '#FFF',
          fontSize: responsive.fontSize(18),
          marginBottom: responsive.number(5)
        }}>
          Sign In
        </Text>
      </TouchableOpacity>
 
      <TouchableOpacity style={{
        backgroundColor: '#16a085',
        justifyContent: 'center',
        alignItems: 'center',
        width: responsive.number(250),
        height: responsive.number(50),
        borderRadius: responsive.number(20)
      }}>
        <Text style={{
          color: '#FFF',
          fontSize: responsive.fontSize(18),
          marginBottom: responsive.number(5)
        }}>
          Sign Up
        </Text>
      </TouchableOpacity>
 
    </View>
  );
}

The results on different-sized devices:

Responsive Design In 393x781 Pixels
Responsive Design In 411x683 Pixels

Project Dependencies

"dependencies": {
    "expo": "~49.0.11",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.4"
}

Conclusion

In conclusion, implementing responsive design in React Native can greatly enhance the consistency and user experience of your app across various devices. By utilizing a utility class like the responsive object we discussed, you can adapt your components to different screen resolutions effortlessly. This approach ensures that your app looks and feels the same, regardless of whether it's running on an iPhone, Samsung, or tablet. So, go ahead and make your React Native app truly responsive!