I would like to add an image to my app, which is built using the react-native
framework with expo
.
I want the Image
component to:
I tried setting width: 100%
. That does not work in react-native
. You have to either set the height to non-auto value or use aspectRatio
(or perhaps there is another approach I'm not aware of). When I use aspectRatio
, the output looks like this:
import { Image } from "expo-image";
import { memo, useState } from "react";
import { View } from "react-native";
import { Text } from "react-native-paper";
const TheImage = require("@/assets/images/tailwind-logo.svg");
export default memo(function MapLoader() {
return (
<View>
<Image source={TheImage} contentFit="cover" style={{ width: "100%", backgroundColor: "red", aspectRatio: 1 }} />
<Text variant="displayLarge">React Native</Text>
</View>
);
});
As you can see, the Image
component (highlighted in red) becomes a square (aspectRatio: 1
) and takes up unnecessary space. My alternative approach was to use the onLoad
prop to update the correct aspectRatio
once the image has loaded. That ultimately works, but causes a brief flash because the component is first rendered with aspectRatio: 1
.
import { Image } from "expo-image";
import { memo, useState } from "react";
import { View } from "react-native";
import { Text } from "react-native-paper";
const TheImage = require("@/assets/images/tailwind-logo.svg");
export default memo(function MapLoader() {
const [aspectRatio, setAspectRatio] = useState<number | undefined>(1);
return (
<View>
<Image
source={TheImage}
contentFit="cover"
style={{ width: "100%", backgroundColor: "red", aspectRatio }}
onLoad={({ source }) => {
setAspectRatio(source.width / source.height);
}}
/>
<Text variant="displayLarge">React Native</Text>
</View>
);
});
My question: how can I render the image so that:
The best solution is to get the image size and set the ratio dynamically. Your code can look something like this for full with and dynamic height:
import React from 'react';
import { Image, View } from 'react-native';
export default function FullWidthLocalImage() {
const source = require('./assets/image.png');
const { width, height } = Image.resolveAssetSource(source);
const aspectRatio = width / height;
return (
<View style={{ width: '100%' }}>
<Image
source={source}
style={{
width: '100%',
aspectRatio,
}}
resizeMode="cover"
/>
</View>
);
}
For remote images you can use Image.getSize