javascript - NextJS : Images loaded from cache don't trigger the onLoad event

标签 javascript reactjs next.js

出于搜索引擎优化和社交媒体链接的原因,我目前正在将 ReactJS 客户端渲染应用程序转换为 NextJS 应用程序。

其中一个转换的组件(基本上是一个等待加载完成然后淡入的图像)在 NextJS 环境中使用后无法按预期工作。

它的行为方式如下:

启用缓存:

  • 第一次加载图像时,会触发 onLoad 事件,从而显示图像。
  • 第二次图像保持隐藏状态,因为从缓存加载图像时不会触发 onLoad 事件。

使用开发工具禁用缓存:

  • onLoad 事件始终有效,因为图像永远不会从缓存中提供。

预期的行为和之前仅使用 ReactJS 实现的行为:

  • 无论图像是否从缓存加载,onLoad 事件都应触发。

当不使用 React 时,此问题通常是由于有人在定义 onload 函数之前设置图像 src 导致的:

let img = new Image()
img.src = "img.jpg"
img.onload = () => console.log("Image loaded.")

应该是:

let img = new Image()
img.onload = () => console.log("Image loaded.")
img.src = "img.jpg"

下面是在 NextJS 中导致相同问题的简化代码:

import React, { useState } from "react"

const Home = () => {
    const [loaded, setLoaded] = useState(false)

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

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

    const handleLoad = () => {
        console.log("Loaded")
        setLoaded(true)
    }

    return (
        <div className="Home" style={homeStyles}>
            <img alt=""
                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>
    )
}

export default Home

最佳答案

由于某人的建议,我最终使用 ImageObject.complete 作为解决方法。

我使用 useRef 引用图像并检查组件安装时的 image.current.complete === true 是否。

这是代码:

import React, { useEffect, useRef, useState } from "react"

const Home = () => {
    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
    }

    const handleLoad = () => setLoaded(true)

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

    return (
        <div className="Home" style={homeStyles}>
            <img alt=""
                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>
    )
}

export default Home

关于javascript - NextJS : Images loaded from cache don't trigger the onLoad event,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59787642/

相关文章:

javascript - 如何动画嵌套 div - jquery?

javascript - 如何将全局风格纳入情感范畴?

reactjs - Paypal 捐赠按钮导致错误 "Unterminated JSX contents"

css - 导航栏折叠按钮不显示 bootstrap 4.5.0 和 Nextjs 9.4.4 的元素

javascript - Mongoose Reconnect 事件在一段时间后没有被触发

javascript - 从 JavaScript 中的字符串中提取所有数字

Javascript requestAnimationFrame 微调器

javascript - 如何在 React Native 中集成 Open Street map ?

next.js - 如何在 Next.js 中创建以特定字符开头的动态路由?

reactjs - 使用 NextJS 和 next-routes,如何处理来自 server.js 和客户端的 404