英文:
How can I display a loading spinner while my Next image component loads when I had a previous image in place?
问题
I'm trying to show a loading spinner (or really any HTML element for that matter) while my image is loading, the thing is I am using this ImageComponent to display an image in a random movie generator, I was able to get the spinner working just with the first image, but after that when I get a new movie the image of the previous movie stays until the new image is loaded.
这是图像组件的代码:
import Image from "next/image";
import { useState } from "react";
export default function ImageComponent(image: PrimaryImage) {
const [loading, setLoading] = useState(true)
function onImageLoad() {
setLoading(false)
console.log("loaded")
}
return (
<div className="relative h-full m-auto">
<div style={{ display: loading ? "block" : "none" }}>
Loading Spinner goes here
</div>
<Image className="object-contain"
src={image.url}
alt="Image"
fill
onLoad={onImageLoad}
priority
style={{ display: loading ? "none" : "block" }}
/>
</div>
)
}
这是完整页面的代码:
"use client"
import { useEffect, useRef, useState } from "react";
import { getMoviesRequest } from "./requests";
import MovieImageComponent from "./components/MovieImage";
export default function Page() {
const moviesCache = useRef<Movie[]>([])
const index = useRef(0)
const [movie, setMovie] = useState<Movie>({
titleText: { text: "" },
primaryImage: { width: 0, height: 0, url: "/default_image.png" },
releaseDate: { day: 0, month: 0, year: 0 }
})
useEffect(() => {
refreshMoviesCache()
}, [])
function refreshMoviesCache() {
// do some stuff to refresh the movies cache
}
function setNewMovie() {
// do some stuff to set a new movie
}
return (
<div>
<h3>
Movie Generator
</h3>
{MovieImageComponent(movie.primaryImage)}
<div className="text-center p-3">
<h1>{movie.titleText.text}</h1>
<h2>{movie.releaseDate.year}</h2>
<button onClick={setNewMovie}>
Otra Pelicula
</button>
</div>
</div>
)
}
Any help would be very much appreciated.
英文:
I'm trying to show a loading spinner (or really any HTML element for that matter) while my image is loading, the thing is I am using this ImageComponent to display an image in a random movie generator, I was able to get the spinner working just with the first image, but after that when I get a new movie the image of the previous movie stays until the new image is loaded.
Here's the code of the image component:
import Image from "next/image";
import { useState } from "react";
export default function ImageComponent(image: PrimaryImage) {
const [loading, setLoading] = useState(true)
function onImageLoad() {
setLoading(false)
console.log("loaded")
}
return (
<div className="relative h-full m-auto">
<div style={{ display: loading ? "block" : "none" }}>
Loading Spinner goes here
</div>
<Image className="object-contain"
src={image.url}
alt="Image"
fill
onLoad={onImageLoad}
priority
style={{ display: loading ? "none" : "block" }}
/>
</div>
)
}
And here is the code of the full page:
"use client"
import { useEffect, useRef, useState } from "react";
import { getMoviesRequest } from "./requests";
import MovieImageComponent from "./components/MovieImage";
export default function Page() {
const moviesCache = useRef<Movie[]>([])
const index = useRef(0)
const [movie, setMovie] = useState<Movie>({
titleText: { text: "" },
primaryImage: { width: 0, height: 0, url: "/default_image.png" },
releaseDate: { day: 0, month: 0, year: 0 }
})
useEffect(() => {
refreshMoviesCache()
}, [])
function refreshMoviesCache() {
// do some stuff to refresh the movies cache
}
function setNewMovie() {
// do some stuff to set a new movie
}
return (
<div>
<h3>
Movie Generator
</h3>
{MovieImageComponent(movie.primaryImage)}
<div className="text-center p-3">
<h1>{movie.titleText.text}</h1>
<h2>{movie.releaseDate.year}</h2>
<button onClick={setNewMovie}>
Otra Pelicula
</button>
</div>
</div>
)
}
Any help would be very much appreciated.
答案1
得分: 1
请使用if语句替代,如下所示:
<div className="relative h-full m-auto">
{loading ?
<div>
加载中的动画放在这里
</div>
:
<Image className="object-contain"
src={image.url}
alt="图片"
fill
onLoad={onImageLoad}
priority
/>
}
</div>
并且您需要在发送新电影请求时每次更改loading
状态。
英文:
use an if statement instead, like this:
<div className="relative h-full m-auto">
{loading ?
<div>
Loading Spinner goes here
</div>
:
<Image className="object-contain"
src={image.url}
alt="Image"
fill
onLoad={onImageLoad}
priority
/>
}
</div>
and you need to change the loading
state every time that you send a request for new movie.
答案2
得分: 0
const [imageUrl, setImageUrl] = useState(你的默认图片URL);
当图片加载完成时,使用 onImageLoad
函数来设置最终的图片URL:
function onImageLoad() {
setLoading(false);
setImageUrl(image.url);
console.log("加载完成");
}
在 src
属性中使用 imageUrl
:
<Image className="object-contain"
src={imageUrl}
alt="图片"
fill
onLoad={onImageLoad}
priority
style={{ display: loading ? "none" : "block" }}
/>
英文:
you could have a state for default image
const [imageUrl,setImageUrl]=useState(yourDefaultImageUrl)
when image loads you have onImageLoad
, and you set the final url here:
function onImageLoad() {
setLoading(false)
setImageUrl(image.url)
console.log("loaded")
}
as src
use imageUrl
<Image className="object-contain"
src={imageUrl}
alt="Image"
fill
onLoad={onImageLoad}
priority
style={{ display: loading ? "none" : "block" }}
/>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论