ifelsething logoifelsething

Show Default Image till Actual Image is Loaded in React Native

Posted By: Harish
Show Default Image till Actual Image is Loaded in React Native

We saw how to show a local asset image stored on a device in react native and how to show a remote image in react native.

For both the scenarios, we directly implemented the image source without any default image. A default image is nothing but a temporary image to show when the image is not loaded yet.

If we do not show a default image, an empty space will be seen at the place of the image and this may lead to the user assuming that there is a bug in the app.

In this post we will use defaultSource prop to show a default image stored on the device. As the default image has to be spontaneous, it's better to use local stored files for this purpose.

Lets see this in action.

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 simple image component with a remote image and a default image .

Import and add Image component with src prop. This prop accepts a direct URL string of the remote image.

We can also use source prop with uri, but for this post, i'm using src prop.

Now add defaultSource prop with a local image path. I placed the image in the assets folder.

Show Default Image till Actual Image is Loaded in React Native

Check below code for better understanding.

//App.tsx
...
import { Image } from 'react-native';
...
<Image
  style={styles.image}
  defaultSource={require('./assets/default-image.png')}
  resizeMode="cover"
  src='https://cdn.pixabay.com/photo/2023/12/07/19/45/tiger-8436227_1280.jpg'
/>

If we run the app,

#for Android
npx react-native run-android

#for ios
npx react-native run-ios

We can see that the remote image is loaded with a default image at first.

Now for better understanding, let's delay the remote image for 2 seconds so that we can see the default image.

Import useEffect, useState and add the setTimeout function to set the source url to the actual URL after 2 seconds.

...
const [src, setSrc] = useState<string | undefined>();
useEffect(() => {
  setTimeout(() => {
    setSrc('https://cdn.pixabay.com/photo/2023/12/07/19/45/tiger-8436227_1280.jpg')
  }, 2000);
}, []);
...
<Image
  ...
  src={src}
/>
...

If you reload the screen, you can see that a default image is shown at first and changes to our remote image after 2 seconds.

Show Default Image till Actual Image is Loaded in React Native

For defaultSource prop to work in an android device or emulator, you have to run the build in release mode cause this prop is ignored in debug mode.

To run the app in release mode, open the project's android folder in Android Studio, wait for a successful build, click on Build -> Select Build Variants.

Change build variant in android studio

Complete code of our example,

//App.tsx
import React, { useEffect, useState } from "react";
import {
  Text,
  StyleSheet,
  SafeAreaView,
  StatusBar,
  View,
  Image,
} from "react-native";

export default function App() {
  const [src, setSrc] = useState<undefined | string>();
  useEffect(() => {
    setTimeout(() => {
      setSrc('https://cdn.pixabay.com/photo/2023/12/07/19/45/tiger-8436227_1280.jpg')
    }, 2000);
  }, []);
  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}>
          show default image till actual image loads
        </Text>
        <Image
          style={styles.image}
          defaultSource={require('./assets/default-image.png')}
          resizeMode="cover"
          src={src}
        />
        <Text style={styles.text}>
          Photo from Pixabay
        </Text>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    margin: 10,
    gap: 20
  },
  text: {
    fontSize: 15,
    color: 'black',
    fontStyle: 'italic'
  },
  image: {
    flexGrow: 1,
    width: '100%'
  }
});

Share is Caring

Related Posts