0

I'm trying to preload an image in useEffect, but it doesn't seem to be downloading the image when app component mounts.

I'm doing something like the following:

export default function App() {
  const [show, setShow] = React.useState(false)

  React.useEffect(() => {
    const image = new Image();
    image.src =
      "https://images.unsplash.com/photo-1601758065893-25c11bfa69b5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1279&q=80";

    setTimeout(() => setShow(true), 10000)
  }, [])

  return (
    <>
      {show && (<img src="https://images.unsplash.com/photo-1601758065893-25c11bfa69b5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1279&q=80 />)}
    </>
  )

The idea here is to download the image ahead of time, so that way when the img is to be displayed, it wouldn't have to download the media.

Unfortunately, useEffect doesn't seem to be triggering the image download. Why doesn't it fetch the image when the component mounts?

cool-grass-2x1ob

Mike K
  • 7,621
  • 14
  • 60
  • 120
  • What are you trying to say not clear – Nooruddin Lakhani Nov 03 '20 at 13:30
  • I'm trying to do something like [this](https://stackoverflow.com/questions/3646036/preloading-images-with-javascript). Preload/lazy load image, so it is ready, when a component needs to use it. Because right now, the image is downloaded only when `show === true`, and the `` is in the DOM. – Mike K Nov 03 '20 at 13:31
  • why do you preload an image and then shows another image show the one you preloaded – elad BA Nov 03 '20 at 13:40
  • Type in question, made the fix – Mike K Nov 03 '20 at 13:58

1 Answers1

1

You have a component called Image, so when you call new Image() you're calling a new instance of the component rendering the native Image constructor useless. So you'll have to build your image by using the createElement function on the document object.

Then instead of a setTimeout listen for the load event to change the show state the moment the image finished loading.

import React from "react";
import Image from "./Image";
import "./styles.css";

export default function App() {
  const [show, setShow] = React.useState(false);

  React.useEffect(() => {
    const image = document.createElement("img");
    image.src =
      "https://images.unsplash.com/photo-1601758065893-25c11bfa69b5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1279&q=80";
    image.onload = () => {
      setShow(true);
    };
  }, []);

  return <div className="App">{show && <Image />}</div>;
}
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32