Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

I’ve been working with React Native for over a year now. And one thing that is driven home by my UX team is the need to provide feedback to the user that something is happening. What I’ve found is that while the React Native <Image/> component provides us with the ability to have a placeholder via the defaultSource property, this can lead to a less than optimal user experience if not implemented properly.


NEW RESEARCH: LEARN HOW DECISION-MAKERS ARE PRIORITIZING DIGITAL INITIATIVES IN 2024.

Get Report


Whether it’s within a ListView implementation or what is known as a Detail View, rendering images within mobile applications requires some finesse, given the UX demands of finely developed mobile applications. Web developers transitioning to React Native need to pay particular attention to how they render images in their application, where the “web way” of rendering images just won’t fly. For example, images rendering as they download is not something that is good UX for mobile applications.

Below is a gif of the YouTube homepage on a desktop loading on a slow network.

How to Use Image Placeholders in React Native: Youtube loading on slow network

We can see that there are grey boxes as placeholders in the images above. We’re going to replicate that behavior in this post, as we take a deep dive into a pattern that you can leverage to easily add a visually pleasing pre-loading placeholder to your application’s Images.

What we’re building

We’ll create a very simple application that displays a two-column grid of Images. We’ll be using a plain <ScrollView/> over a <ListView/> component because a <ListView/> would simply make things more complicated than necessary to demonstrate this pattern, though it is advised to use a <ListView/> for this pattern for optimal performance. The goal of this post is to drive home the need for a multi-phase approach for rendering with placeholder images.

How to Use Image Placeholders in React Native: Placeholder Images

As you’ll soon learn, the code for this application is relatively simple. But in case you’re new to using React JS and React Native, I’ll explain all of it.

If you’re like me, you might want to see this running right away. I’ve setup a github repo here.

If you’re new to the React Native ecosystem, it might be prudent to review the code structure first. Otherwise, feel free to jump to the next section.

Contents of index.ios.js

import React, {
    // All necessary imports
} from 'react-native';

// We'll place some constants here

// Define needed styles
const styles = StyleSheet.create({ });

class Placeholder extends Component {
    // Initial state
    state = { };

    // Step #4 (Self-bound function)
    // We will update the state of the application so that images can render
    onAfterLoad = (data) => { };
    
    // Step #1 & #2
    // Here we’ll fetch JSON for images to be displayed
    componentWillMount() { }

    // This will be responsible for rendering the image components
    buildImages(data) { }

    // Step #3 and #5
    // Render the main view and child images
    render() { }
}

How to setup image placeholders

One of the best ways to envision how this will work is thinking about a timeline.

How to Use Image Placeholders in React Native 3

The steps break down like this:

  1. componentWillMount() executes. This gives us some intelligence that our component will come to life, so we kick off the load, which is the next step.
  2. Inside the body of componentWillMount(), we’ll initiate a fetch() for the JSON data. Keep in mind that these requests are asynchronous, making the next step rather crucial for two reasons. First, we have no idea how long it’s going to take for the fetch() to finish. Second, if we don’t show something meaningful, the user won’t get the rapid visual feedback that they have become accustomed to with high-performing mobile applications. Without that feedback, they will get the wrong impression of the application’s ability to function and may elect to close it.
  3. In this step, the render() phase of the component lifecycle kicks in. What you must keep in mind is that we don’t have data to display just yet, so we’ll have to show the user something. We could display a loading indicator, but for some application designs, that pattern won’t work. So we’re going to render enough placeholders to fill the screen.
  4. Assuming step #2 completes successfully, the fetch() success callback handler will trigger a new state, passing in the newly fetched data. For simplicity’s sake, I did not put much error handling here.
  5. This step calls this.setState() with an updated state object containing the image objects as a member labeled data, forcing a refresh of the render cycle.
  6. Now that we have data in our state object, we’ll render <Image/> components with both the placeholder image and the actual source URI will point to the images the user will want to see.

Here is a video that demonstrates what rendering of the view looks like with and without the placeholder images. On the left, you’ll find a version of the application that only renders the <Image/> components after the fetch has successfully completed, versus the two-pass approach described above.

Here are some things to think about as you review the code below.

  • You’ll find that the buildImages() method, which is called by render(), is responsible for iterating over the data and producing instances of <Image/>. It determines if we have data in the local state object (line #92) and will pad the array with ten undefines.
  • When the fetch() completes, we’ll enter the second phase of the render cycle, where we expect to have data with URIs for the images we expect to render. buildImages() will at that point use the data to configure the images to the proper URLs.
  • The last thing to think about is that we must set the defaultSource prop for the <Image/> component to the placeholder. This allows the <Image/> components to fetch the image assets, while allowing to display something for the user.
  • To exacerbate the situation, I’m using Math.random() as a cache buster and am simulating 3G network conditions with information from this blog post. Afterall, slow network is exactly why we’re doing all of this work.

There you have it. The multi-phase approach to rendering images with placeholders while we wait for data to come in is not a difficult approach to configure in our applications.

Conclusion

In this article, we explored using a multi-phase render approach to a view that renders two columns of images using placeholders to assist with the user experience. In the next post, I’ll work to tackle this approach coupled with animating the fade-in of the images.

Thank you for reading! Has this article helped you? Please share it via social media channels.

Have questions or any suggestions for improvement? Post them below.

Posted in Application Development
Share this

Jay Garcia

Jay Garcia is co-founder of Modus Create. He is a veteran of the U.S. Air Force with 20-plus years of technology and consulting experience in leading RIA development for companies around the world. He is a co-organizer of the NoVa.JS and NYC.JS meetups, and is actively involved in the software communities that provide business frameworks and technologies, which enable rich mobile and desktop web experiences.
Follow

Related Posts

  • React Navigation and Redux in React Native Applications
    React Navigation and Redux in React Native Applications

    In React Native, the question of “how am I going to navigate from one screen…

  • Using ES2016 Decorators in React Native
    Using ES2016 Decorators in React Native

    *picture courtesy of pixabayDecorators are a popular bit of functionality currently in Stage 1 of…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers Old
  • Let’s talk
  • EN
  • FR