Image Load Events in React Native
Posted By: Harish

We have seen onLayout callback to know the width, height and position of the rendered image.
Like this, we also have onLoadStart callback which is called when image starts loading, onLoad callback is called when the image is rendered and finally onLoadEnd callback when the image finishes loading completely.
In this example, we will use these callbacks to show a loading indicator when new image loads.
Lets see this 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 where a loading indicator is shown when a new image is loaded.
First we will take a simple remote image and see how these callbacks are called.
Import and add Image
component with a remote image source link.
Now add all three onLoadStart
, onLoad
and onLoadEnd
callbacks with console logs.
//App.tsx
...
import { Image } from 'react-native';
...
<Image
onLoad={e => {
console.log("load ", e.nativeEvent);
}}
onLoadStart={() => {
console.log("load start");
}}
onLoadEnd={() => {
console.log("load end");
}}
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
We can see logs for different callbacks. For the onLoad
callback, I logged its nativeEvent to see the details of the image in the log.
LOG load start
LOG load {"source": {"height": 205.5, "uri": "https://iet-images.s3.ap-south-1.amazonaws.com/gif-rn-android.gif", "width": 100}, "target": 147}
LOG load end
From above logs, you can see that onLoadStart
callback is called when the image is started to load, onLoad
when image is loading and onLoadEnd
when it completely loads.
So, we will use these callbacks to show a simple loading indicator when the image loads.
Import useState
from react and create two new state variables, isLoading
and remoteUrl
.
isLoading is to show a loading indicator and it accepts boolean values.
Import ActivityIndicator from react-native for indicator.
...
{
isLoading
&& <ActivityIndicator
size='large'
color='darkgreen'
animating={true}
/>
}
...
src is to set a new remote url on click of a button. For this, import the Button
component from react-native.
You can check the complete code below.
Now, if we load the app again, you can see the like below image.

From the above gif, we can see that a loading indicator is shown when a new image starts to load and disappears when the image completely loads.
Complete code of our example,
//App.tsx
import React, { useState } from "react";
import {
Text,
StyleSheet,
SafeAreaView,
StatusBar,
View,
Image,
ActivityIndicator,
Button,
} from "react-native";
export default function App() {
const [isLoading, setIsLoading] = useState<boolean>(false);
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}>
image load events in react native
</Text>
{
isLoading
&& <ActivityIndicator
size='large'
color='darkgreen'
animating={true}
/>
}
<Image
onLoad={e => {
console.log("load ", e.nativeEvent);
}}
onLoadStart={() => {
setIsLoading(true);
console.log("load start ");
}}
onLoadEnd={() => {
setIsLoading(false);
console.log("load end");
}}
style={styles.image}
resizeMode="cover"
src={remoteUrl}
/>
<Button
title="Load"
onPress={() => {
setRemoteUrl('https://iet-images.s3.ap-south-1.amazonaws.com/gif-rn-android.gif')
}}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 10,
gap: 20
},
text: {
fontSize: 15,
color: 'black',
fontStyle: 'italic'
},
image: {
flexShrink: 1,
width: '100%',
height: 300
}
});