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:
- fill the width of its parent component
- fit the image's original aspect ratio
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:
- it fills the parent container
- it fits the actual image (image above)
- it does so without rendering flashes

