Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 44 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Handling Media in React: Optimizing Images and Loading States

Master media in React by learning to handle loading states, implement smart fallbacks for broken images, and optimize your assets for better performance.

ReactMediaImagesPerformanceFrontendWeb Developmentjavascript

Previously in this course, we explored building a favorites list to manage complex state. This lesson shifts our focus to the visual layer of our movie-browser app: rendering external media.

In a professional application, you cannot assume an image will always load instantly—or even load at all. Network latency, broken API links, and slow connections are facts of life. To build a truly modern UI, you must handle these scenarios gracefully.

Understanding Media from First Principles

In React, the <img> tag is just an HTML element, but when it points to an external source, it behaves like an asynchronous operation. The browser begins downloading the file, and during this time, the component is in a "loading" state.

If the server returns a 404 or the URL is malformed, the browser fires an onError event. If we ignore these events, we end up with "broken" UI—empty white rectangles or ugly browser-default icons that ruin the user experience.

Building a Robust Image Component

Instead of placing raw <img> tags throughout your app, it is a best practice to create a reusable MoviePoster component. This encapsulates the logic for loading states and error fallbacks.

JSX
import { useState } from CE9178">'react';

const MoviePoster = ({ src, alt, title }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [hasError, setHasError] = useState(false);

  // Fallback image if the API returns a broken link
  const fallbackSrc = CE9178">'/placeholder-movie.png';

  return (
    <div className="poster-container">
      {isLoading && <div className="spinner">Loading...</div>}
      
      {!hasError ? (
        <img
          src={src}
          alt={alt}
          onLoad={() => setIsLoading(false)}
          onError={() => {
            setHasError(true);
            setIsLoading(false);
          }}
          style={{ display: isLoading ? CE9178">'none' : CE9178">'block' }}
        />
      ) : (
        <img src={fallbackSrc} alt="Placeholder" />
      )}
    </div>
  );
};

Key Techniques Explained

  1. The onLoad Event: This fires once the browser has successfully fetched the image. We use it to set isLoading to false, revealing the image only after it's ready.
  2. The onError Event: This is your safety net. If the image fails to load, we update our state to swap the broken source for a local, reliable placeholder.
  3. Performance Tip: Notice the style={{ display: isLoading ? 'none' : 'block' }}. This ensures the browser doesn't show a "broken" icon while the image is still being fetched.

Optimizing Media Rendering

Rendering high-resolution images for every device is a performance killer. While advanced image optimization usually happens on the server (using CDNs like Cloudinary or Imgix), you can contribute at the component level:

  • Lazy Loading: Add the loading="lazy" attribute to your <img> tags. This tells the browser to wait until the image is near the viewport before downloading it, significantly improving initial page load times.
  • Aspect Ratio: Use CSS aspect-ratio to reserve space for the image before it loads. This prevents "layout shift," where the page content jumps around as images pop into existence.

Hands-on Exercise

Update your MovieCard component in the movie-browser project to use a custom MoviePoster component.

  1. Create a new file MoviePoster.jsx.
  2. Move your current img tag logic into this component.
  3. Implement the onLoad and onError handlers as shown above.
  4. Add a CSS class to your poster-container that sets a consistent aspect-ratio: 2/3 to keep your movie grid perfectly aligned while images load.

Common Pitfalls

  • Infinite Loops with onError: Never set the src to the same URL that failed inside the onError handler. This will cause an infinite loop of error events. Always point to a local, static fallback image.
  • Ignoring Accessibility: Always provide a descriptive alt tag. If the image is decorative, use alt="". If it's a movie poster, use the movie title.
  • Over-fetching: Don't render full-resolution 4K posters in a small search results list. Ensure your API endpoint provides a "thumbnail" or "poster_small" version of the URL.

Recap

Handling media in React is about anticipating the unpredictable nature of the network. By managing images with dedicated state for loading and errors, you create a resilient interface. Remember to use loading="lazy" to keep your app performant and ensure you provide fallbacks to prevent empty UI blocks.

Up next: We will begin our unit testing journey, starting with an introduction to testing our React components.

Previous lessonBuilding a Favorites ListNext lesson Introduction to Testing
Back to Blog

Similar Posts

ReactReactJune 24, 20263 min read

Setting Up with Vite: A Professional React Development Environment

Learn how to initialize a professional React project using Vite. We’ll cover the project directory structure and how to launch your fast development environment.

Read more
ReactJune 25, 20263 min read

Finalizing the Movie Browser: A Professional Guide to QA and Testing

Part of the course

React Fundamentals: Build Modern UIs from Scratch

beginner · Lesson 44 of 49

  1. 1

    Introduction to Component-Based Architecture

    4 min
  2. 2

    Understanding the Virtual DOM

    4 min
  3. 3

    Setting Up with Vite

    3 min

Master project finalization by learning systematic QA, bug squashing, and UX refinement techniques to ensure your React movie browser is production-ready.

Read more
ReactReactJune 25, 20263 min read

Fetching Data from an API: A Practical React Guide

Master the fetch API in React to retrieve external data. Learn to perform asynchronous requests and store JSON responses in your component state effectively.

Read more
4

Mastering JSX Syntax

4 min
  • 5

    Creating Static Components

    3 min
  • 6

    Styling Components

    3 min
  • 7

    Passing Data with Props

    3 min
  • 8

    Dynamic Movie Cards

    3 min
  • 9

    Component Composition

    3 min
  • 10

    Conditional Rendering

    3 min
  • 11

    Rendering Lists of Data

    4 min
  • 12

    The Key Prop Explained

    4 min
  • 13

    Introduction to React State

    4 min
  • 14

    Managing State with useState

    3 min
  • 15

    Building an Interactive Search Bar

    3 min
  • 16

    Handling Click Events

    4 min
  • 17

    Updating State Based on Previous State

    4 min
  • 18

    Filtering the Movie List

    3 min
  • 19

    Handling Form Submissions

    3 min
  • 20

    Controlled Components

    4 min
  • 21

    Event Bubbling and Propagation

    3 min
  • 22

    Building a Movie Filter Toggle

    3 min
  • 23

    Introduction to Side Effects

    4 min
  • 24

    useEffect Dependencies

    4 min
  • 25

    Fetching Data from an API

    3 min
  • 26

    Handling Loading States

    3 min
  • 27

    Managing Errors

    3 min
  • 28

    Cleanup Functions in useEffect

    3 min
  • 29

    Debouncing Search Input

    3 min
  • 30

    Refactoring for Clean Code

    3 min
  • 31

    Folder Structure Best Practices

    4 min
  • 32

    Extracting Custom Hooks

    3 min
  • 33

    Prop Drilling and Context API

    3 min
  • 34

    Polishing the UI

    3 min
  • 35

    Finalizing the Movie Browser

    3 min
  • 36

    Review of Component Lifecycle

    4 min
  • 37

    Review of State Management

    4 min
  • 38

    Building a Modal Component

    3 min
  • 39

    Introduction to PropTypes

    3 min
  • 40

    Performance Optimization Basics

    3 min
  • 41

    Handling Browser History

    3 min
  • 42

    Working with LocalStorage

    3 min
  • 43

    Building a Favorites List

    3 min
  • 44

    Handling Media in React

    3 min
  • 45

    Introduction to Testing

    4 min
  • 46

    Debugging React Apps

    4 min
  • 47

    Deployment Basics

    3 min
  • 48

    Using External Libraries

    3 min
  • 49

    Advanced

    3 min
  • View full course