Skip to content Skip to sidebar Skip to footer

Nextjs: Images Loaded From Cache Don't Trigger The Onload Event

I am currently in the process of converting a ReactJS client side rendered application to a NextJS application for search engine optimization and social media linking reasons. One

Solution 1:

I ended up using ImageObject.complete as a workaround thanks to someone's suggestion.

I used useRef to reference the image and checked if the image.current.complete === true on component mount.

Here is the code:

importReact, { useEffect, useRef, useState } from"react"constHome = () => {
    const [loaded, setLoaded] = useState(false)

    const image = useRef()

    const homeStyles = {
        width: "100%",
        height: "96vh",
        backgroundColor: "black"
    }

    const imgStyles = {
        width: "100%",
        height: "100%",
        objectFit: "cover",
        opacity: loaded ? 1 : 0
    }

    consthandleLoad = () => setLoaded(true)

    useEffect(() => {
        if (image.current.complete) setLoaded(true)
    }, [])

    return (
        <divclassName="Home"style={homeStyles}><imgalt=""ref={image}onLoad={handleLoad}src="https://images.unsplash.com/photo-1558981001-5864b3250a69?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80"style={imgStyles}
            /></div>
    )
}

exportdefaultHome

Solution 2:

From Next.js v11.0.2-canary.4 onwards, one can directly use onLoadingComplete prop.

<Image src={src} onLoadingComplete={() =>setLoaded(true)} />

How does this compare with other options??

  • You get to keep using the awesome next/image component instead of unoptimized img tag without any extra code or dealing with refs yourself.

Solution 3:

If you are using the new Image component from nextjs 10, which does not support a forward ref, you can modify the workaround with

const [loaded, setLoaded] = useState(false)
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
  if ((ref.current?.firstChild?.firstChildasHTMLImageElement | undefined)?.complete) {
    setLoaded(true)
  }
}, [])

return<divref={ref}><Imagesrc={src}onLoad={() => setLoaded(true)}/>
       </div>

Solution 4:

I only want to add to @mohamed-seif-khalid answer that I had to add a check in useEffect if ref consist anything, because my render continued to break.

useEffect(() => {
    if (image.current && image.current.complete) {
      handleImageLoad()
    }
  }, []);

Post a Comment for "Nextjs: Images Loaded From Cache Don't Trigger The Onload Event"