NextJS:从缓存加载的图像不会触发 onLoad 事件 [英] NextJS: Images loaded from cache don't trigger the onLoad event

查看:130
本文介绍了NextJS:从缓存加载的图像不会触发 onLoad 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

它的行为方式如下:

缓存已启用:

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

使用 devtools 禁用缓存:

  • onLoad 事件始终有效,因为图像从未从缓存中提供.

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

  • onLoad 事件应触发图像是否从缓存中加载.

当不使用React时,这个问题通常是因为有人在定义onload函数之前设置了图像src:

let img = new Image()img.src = "img.jpg"img.onload = () =>console.log("图片已加载.")

应该是:

let img = new Image()img.onload = () =>console.log("图片已加载.")img.src = "img.jpg"

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

import React, { useState } from "react"const Home = () =>{const [加载,setLoaded] = useState(false)const homeStyles = {宽度:100%",高度:96vh",背景颜色:黑色"}const imgStyles = {宽度:100%",高度:100%",objectFit: "封面",不透明度:加载?1 : 0}const handleLoad = () =>{console.log("加载")设置加载(真)}返回 (<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=1380&q=1380&样式={imgStyles}/>

)}导出默认首页

解决方案

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

我使用 useRef 来引用图像并检查组件安装上的 image.current.complete === true.

代码如下:

import React, { useEffect, useRef, useState } from "react"const Home = () =>{const [加载,setLoaded] = useState(false)const 图像 = useRef()const homeStyles = {宽度:100%",高度:96vh",背景颜色:黑色"}const imgStyles = {宽度:100%",高度:100%",objectFit: "封面",不透明度:加载?1 : 0}const handleLoad = () =>设置加载(真)useEffect(() => {如果(image.current.complete)setLoaded(真)}, [])返回 (<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=1380&q=1380&样式={imgStyles}/>

)}导出默认首页

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 of the components converted, which is basically an image that waits until it's finished loading then fades in, is not working as expected after it is used in a NextJS environment.

It behaves in the following manner:

Cache Enabled:

  • The first time the image loads and the onLoad event triggers thus showing the image.
  • The second time the image stays hidden because the onLoad event doesn't trigger when the image is loaded from cache.

Cache Disabled using devtools:

  • The onLoad event always works because the image is never served from cache.

Expected behavior and the behavior previously achieved with using just ReactJS:

  • The onLoad event should trigger whether the image was loaded from the cache or not.

When not using React this problem is usually caused when someone sets the images src before defining a onload function:

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

Which should be:

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

Here is simplified code that causes the same problem in 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

解决方案

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:

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

这篇关于NextJS:从缓存加载的图像不会触发 onLoad 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆