NextJS:从缓存加载的图像不会触发 onLoad 事件 [英] NextJS: Images loaded from cache don't trigger the onLoad event
问题描述
出于搜索引擎优化和社交媒体链接的原因,我目前正在将 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屋!