Image Loading Progress in React Native
Published On: 2024-05-18
Posted By: Harish

When an image is rendered, we can get the metrics and load events of the image.
With these, we also have onProgress callback, which returns loading progress of an image. We will get the data loaded at a particular time.
Lets see this with a working example.
Create A New Project
Create a new react-native project by using npx. Check documentation for creating a new react native project.
npx react-native@latest init ImageRN
Example Implementation
We will create a screen with an image and load button. And we will show load percentage on the new image load.
Import and add Image
component with a remote image source link. This link will be changed to a new image link on the press of a button.
//App.tsx
...
import { Image } from 'react-native';
...
<Image
style={styles.image}
resizeMode="cover"
src='https://iet-images.s3.ap-south-1.amazonaws.com/fav.png'
/>
...
If we run the app,
#for Android
npx react-native run-android
#for ios
npx react-native run-ios
Initial image will be loaded.
Now, we need to change the src url on click of a button to a new one.
So, we need to import the Button
component and useState
to store links.
Create a state variable remoteUrl
with initial remote url. And set a new url on click of a button.
Above code can be found below complete code block.
Now the main part of this post is, showing loading progress.
Add onProgress
callback and console log the returned event's nativeEvent object.
LOG {"loaded": 10724, "target": 147, "total": 10724}
LOG {"loaded": 17011, "target": 147, "total": 619804}
LOG {"loaded": 51716, "target": 147, "total": 619804}
LOG {"loaded": 103940, "target": 147, "total": 619804}
LOG {"loaded": 138756, "target": 147, "total": 619804}
LOG {"loaded": 573956, "target": 147, "total": 619804}
LOG {"loaded": 619804, "target": 147, "total": 619804}
You will get loaded objects with current loaded data and total data to download. Using this we will show progress percentage.
...
<Image
...
onProgress={(e) => {
const info = e.nativeEvent;
setProgress(~~Math.abs(info.loaded / info.total * 100));
}}
/>
...
With the above calculation we will get the percentage. We are rounding off the percentage of loaded divided by total data to load.

From the above gif, we can see the load percentage of the new image.
We can also use a loading indicator on image load if needed.
Complete code of our example,
//App.tsx
import React, { useState } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
Image,
Button
} from "react-native";
export default function App() {
const [progress, setProgress] = useState<number>(0);
const [remoteUrl, setRemoteUrl] = useState<string>('https://iet-images.s3.ap-south-1.amazonaws.com/fav.png');
return (
<SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>
<StatusBar
barStyle="dark-content"
/>
<View style={styles.container} >
<Text style={styles.text}>
ifelsething.com
</Text>
<Text style={styles.text}>
progress of loading image in react native
</Text>
<Image
style={styles.image}
resizeMode="cover"
onProgress={(e) => {
const info = e.nativeEvent;
setProgress(~~Math.abs(info.loaded / info.total * 100));
}}
src={remoteUrl}
/>
<Button
title="Load"
onPress={() => {
setRemoteUrl('https://iet-images.s3.ap-south-1.amazonaws.com/gif-rn-android.gif')
}}
/>
<Text style={styles.text}>
progress: {progress}%
</Text>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20,
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
image: {
width: 300,
height: 300,
alignSelf: 'center'
}
});