How to Build Responsive Mobile Apps on React-Native?

How to Build Responsive Mobile Apps on React-Native?

Founder @ ProductCrafters
Reading Time: 3 minutes

Styling of the mobile app may be tricky – there are a lot of screens sizes and screen ratios, especially for Android devices. When you develop an app, in most cases you have only one wireframe version in Invision/Sketch per platform. For example in our last project, we targeted iOS only and had wireframes for iPhone X and iPhone 8 only. Suddenly the client decided to support iPhone 8 Plus, 6, 6 Plus, XS, XR. This year we will see the new iPhone with different screen sizes and dimensions. I’m sure it will be a new requirement. If we just hardcoded in the original design for iPhone X, it would cause us big troubles just before the project launch.

How to create a responsive react-native app from a mockup?

Responsive React Native app

Step 1: Move from physical to density-independent pixels

According to docs:

 All dimensions in React Native are unitless, and represent density-independent pixels (wiki).

Any mockup is designed with physical pixels. So we need to convert pixels to density-independent pixels.

We calculate relative width and height for the current screen size. 

export const deviceWidth = Dimensions.get('window').width
export const deviceHeight = Dimensions.get('window').height
export const calcHeight = x => PixelRatio.roundToNearestPixel((deviceHeight * x) / 100)
export const calcWidth = x => PixelRatio.roundToNearestPixel((deviceWidth * x) / 100)

We avoid using ANY hardcoded constants in the layout. It’s very tempting to use +10 px to align space between to controls. But if we do this and somebody will run the app on a device with another screen density/ratio this single line will make a lot of trouble for us.

headerText: {
  paddingTop: calcHeight(4),
  paddingLeft: calcWidth(16.5),
  paddingRight: calcWidth(16.5),
  textAlign: 'center',
  lineHeight: 17

Step 2: Use different styles/const in React-Native for different device models

React Native beauty app

In our experience, we got a situation when responsive styles work great for all devices. But there are devices with much wider screens (iPhone X vs iPhone iPad) that have a much different aspect ratio.  In this situation, responsive styles will be not enough.

Our responsive helpers use a linear function to the width or height of the device. Linear responsiveness is not a universal instrument ’cause if you start using it for fonts or borders/paddings, you will see how ugly can be the design of your app. The main use of linear responsive helpers is a layout, like columns width, sidebars, or items grid.

import { Dimensions, Platform } from 'react-native'

export const isIphoneX = () => {
  const dimen = Dimensions.get('window')
  return (
    Platform.OS === 'ios' && !Platform.isPad && !Platform.isTVOS && 
    (dimen.height === 812 || dimen.width === 812 || (dimen.height === 896 || dimen.width === 896))

This is our helper function to ensure, the current device is iPhone X. Now when we know this, let’s apply the appropriate style:

const style = isPhoneX() ? style1 : style2

Step 3: Different layouts for smartphones and tablets, portrait and landscape mode

Different layouts for smartphones and tablets, portrait and landscape mode


Are you working on the app that also may be launched on the tablet, start from UX for it? How do you want to rebuild the app interface for the much wider screen? What controls do you want to put on free space? What controls/components do you need to remove if the screen is much narrower? 

Discuss it with the client as soon as possible to avoid spending time on reworking functional screens. Make sure you have approved the mockup before working on styles.

Step 4: Pictures

To get astonishing image quality on React-Native and at the same time save internet traffic, we need to ask the backend for image size for specific mobile app screen sizes. For sure while the image is loading we will show the spinner.

So now we need to do vice versa – convert density-independent pixels that we have in image style to physical pixels, that backend works with. In BeatyAdvisor project we use Cloudinary for easy image processing It allows resizing images using single param in URL. To calculate it there is a built-in helper:

const imgWidthDP = 68
const imgWidth = PixelRatio.getPixelSizeForLayoutSize(imgWidthPx)