Tips for React Native Images (or saying goodbye to trial and error)

After building three different mobile applications with React Native, I realised that when it comes to images, I keep doing a decent amount of trial and error! While there are two different articles in the React Native documentation (https://facebook.github.io/react-native/docs/images.html and https://facebook.github.io/react-native/docs/image.html), there are several scenarios that are not covered. In this article I show some recipes for common use cases.

Making your images responsive

You may not realise how different images look in the exact same layout with different resolutions. To put things in perspective, an iPhone 5 has a resolution of 320x568, while an iPhone 6 plus has a resolution of 414x736. Here’s what these different resolutions can do to your images:

iphone 5

Clearly the designer had an iPhone 5 (perhaps even 6) in mind when designing that image. But here’s how the same screen looks in an iPhone 6 plus:

iphone 6 plus

Notice how lonely that cigarette looks! Clearly not as nice.

Turns out that making images responsive, is not really that hard. It may however require some tweaking of flex ratios, but once you get the flex config right, then it’s a matter of remembering to set the height and width to undefined!

<Image
style={{flex:1, height: undefined, width: undefined}}
source={require('../../../assets/images/onboarding-how-it-works.png')}
resizeMode="contain"
/>

Note: The other thing to keep in mind is the resizeMode. For this particular scenario, I’d say you probably will want “contain”, but there’s more on this later.

I know, very simple tip, but here’s how it looks now:

responsive in iPhone 6 plus

Certainly not perfect, but a whole lot better!

Tip: if you want an easire way to test your app in different resolutions you should check out https://github.com/machadogj/react-native-components-viewer (any feedback and PRs are welcome!)

Background Image

The image component accepts children props as does View, the reason for which you could potentially use an Image as a container with a background. There are some caveats though, with a View if you want to expand to your parent’s size, you can use {flex: 1, alignSelf: ‘stretch’}, or you can use {position:'absolute',left:0,right:0,top:0,bottom:0}.

However because images will try to set the width and height based on the actual size of the image, you need to override these style properties:

<Image
style={{
flex: 1,
alignSelf: 'stretch',
width: undefined,
height: undefined
}}
source={require('../../assets/images/onboarding-how-it-works.png')}
>
{ children }
</Image>

Once your image has the size of the container, and that you can add content to it, you will want to know how to use the right resizeMode. Now let’s see how the resizeMode will affect a background image like the one in the documentation:

With resizeMode set to stretch, the image will lose it’s original aspect ratio and will cover the entire frame:

When set to cover the image will maintain it’s original aspect ratio, but will still cover the entire containing frame. If the image can’t fill the entire frame, the it will be scaled up until it does and then it will be centered. You can easily see this here:

Finally, if you use contain the image will maintain it’s original aspect ratio, but it will try to fit as much of the image as possible. It will also center the image, but if the image can cover all the frame it will actually scale the image down until the image fits entirely. Again, this can easily be seen here:

The other options are repeat and center. Repeat is pretty much self explanatory, and I couldn’t find differences between contain and center.

Another thing you might need to do, is set the “backgroundColor” to “transparent” in some components so that it blends well with the background.

Round Images

As you probably know, making things round in RN entails setting the same width and height, and then a borderRadius that is half of the width/height.

<Image
style={{
alignSelf: 'center',
height: 150,
width: 150,
borderWidth: 1,
borderRadius: 75
}}
source={{uri:'https://facebook.github.io/react/img/logo_og.png'}}
resizeMode="stretch"
/>

What is interesting to know when it comes to images, is how to fit a potentially not squared image in a circle. For doing that, I found the resizeMode “cover” to be particularly usefule. Here you can compare different images:

resizeMode: ‘contain’

And with cover:

resizeMode: ‘cover’

What if you want a rounded image to take as much space as possible? One way to circumvent not knowing the size (width/height) in advanced is to use a View as the frame (you can use something like flex:1, alignSelf:'stretch’ in order to take more space, but remember that flex uses ratios so it will actually depend on your other items). You can use the View’s onLayout to measure the size of the space that the image will have.

Hope any of these helped!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.