如何在我的Next图像组件加载时显示加载动画,当我已经放置了先前的图像?

huangapple go评论103阅读模式
英文:

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.

这是图像组件的代码:

  1. import Image from "next/image";
  2. import { useState } from "react";
  3. export default function ImageComponent(image: PrimaryImage) {
  4. const [loading, setLoading] = useState(true)
  5. function onImageLoad() {
  6. setLoading(false)
  7. console.log("loaded")
  8. }
  9. return (
  10. <div className="relative h-full m-auto">
  11. <div style={{ display: loading ? "block" : "none" }}>
  12. Loading Spinner goes here
  13. </div>
  14. <Image className="object-contain"
  15. src={image.url}
  16. alt="Image"
  17. fill
  18. onLoad={onImageLoad}
  19. priority
  20. style={{ display: loading ? "none" : "block" }}
  21. />
  22. </div>
  23. )
  24. }

这是完整页面的代码:

  1. "use client"
  2. import { useEffect, useRef, useState } from "react";
  3. import { getMoviesRequest } from "./requests";
  4. import MovieImageComponent from "./components/MovieImage";
  5. export default function Page() {
  6. const moviesCache = useRef<Movie[]>([])
  7. const index = useRef(0)
  8. const [movie, setMovie] = useState<Movie>({
  9. titleText: { text: "" },
  10. primaryImage: { width: 0, height: 0, url: "/default_image.png" },
  11. releaseDate: { day: 0, month: 0, year: 0 }
  12. })
  13. useEffect(() => {
  14. refreshMoviesCache()
  15. }, [])
  16. function refreshMoviesCache() {
  17. // do some stuff to refresh the movies cache
  18. }
  19. function setNewMovie() {
  20. // do some stuff to set a new movie
  21. }
  22. return (
  23. <div>
  24. <h3>
  25. Movie Generator
  26. </h3>
  27. {MovieImageComponent(movie.primaryImage)}
  28. <div className="text-center p-3">
  29. <h1>{movie.titleText.text}</h1>
  30. <h2>{movie.releaseDate.year}</h2>
  31. <button onClick={setNewMovie}>
  32. Otra Pelicula
  33. </button>
  34. </div>
  35. </div>
  36. )
  37. }

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:

  1. import Image from "next/image";
  2. import { useState } from "react";
  3. export default function ImageComponent(image: PrimaryImage) {
  4. const [loading, setLoading] = useState(true)
  5. function onImageLoad() {
  6. setLoading(false)
  7. console.log("loaded")
  8. }
  9. return (
  10. <div className="relative h-full m-auto">
  11. <div style={{ display: loading ? "block" : "none" }}>
  12. Loading Spinner goes here
  13. </div>
  14. <Image className="object-contain"
  15. src={image.url}
  16. alt="Image"
  17. fill
  18. onLoad={onImageLoad}
  19. priority
  20. style={{ display: loading ? "none" : "block" }}
  21. />
  22. </div>
  23. )
  24. }

And here is the code of the full page:

  1. "use client"
  2. import { useEffect, useRef, useState } from "react";
  3. import { getMoviesRequest } from "./requests";
  4. import MovieImageComponent from "./components/MovieImage";
  5. export default function Page() {
  6. const moviesCache = useRef<Movie[]>([])
  7. const index = useRef(0)
  8. const [movie, setMovie] = useState<Movie>({
  9. titleText: { text: "" },
  10. primaryImage: { width: 0, height: 0, url: "/default_image.png" },
  11. releaseDate: { day: 0, month: 0, year: 0 }
  12. })
  13. useEffect(() => {
  14. refreshMoviesCache()
  15. }, [])
  16. function refreshMoviesCache() {
  17. // do some stuff to refresh the movies cache
  18. }
  19. function setNewMovie() {
  20. // do some stuff to set a new movie
  21. }
  22. return (
  23. <div>
  24. <h3>
  25. Movie Generator
  26. </h3>
  27. {MovieImageComponent(movie.primaryImage)}
  28. <div className="text-center p-3">
  29. <h1>{movie.titleText.text}</h1>
  30. <h2>{movie.releaseDate.year}</h2>
  31. <button onClick={setNewMovie}>
  32. Otra Pelicula
  33. </button>
  34. </div>
  35. </div>
  36. )
  37. }

Any help would be very much appreciated.

答案1

得分: 1

请使用if语句替代,如下所示:

  1. <div className="relative h-full m-auto">
  2. {loading ?
  3. <div>
  4. 加载中的动画放在这里
  5. </div>
  6. :
  7. <Image className="object-contain"
  8. src={image.url}
  9. alt="图片"
  10. fill
  11. onLoad={onImageLoad}
  12. priority
  13. />
  14. }
  15. </div>

并且您需要在发送新电影请求时每次更改loading状态。

英文:

use an if statement instead, like this:

  1. &lt;div className=&quot;relative h-full m-auto&quot;&gt;
  2. {loading ?
  3. &lt;div&gt;
  4. Loading Spinner goes here
  5. &lt;/div&gt;
  6. :
  7. &lt;Image className=&quot;object-contain&quot;
  8. src={image.url}
  9. alt=&quot;Image&quot;
  10. fill
  11. onLoad={onImageLoad}
  12. priority
  13. /&gt;
  14. }
  15. &lt;/div&gt;

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:

  1. function onImageLoad() {
  2. setLoading(false);
  3. setImageUrl(image.url);
  4. console.log("加载完成");
  5. }

src 属性中使用 imageUrl

  1. <Image className="object-contain"
  2. src={imageUrl}
  3. alt="图片"
  4. fill
  5. onLoad={onImageLoad}
  6. priority
  7. style={{ display: loading ? "none" : "block" }}
  8. />
英文:

you could have a state for default image

  1. const [imageUrl,setImageUrl]=useState(yourDefaultImageUrl)

when image loads you have onImageLoad, and you set the final url here:

  1. function onImageLoad() {
  2. setLoading(false)
  3. setImageUrl(image.url)
  4. console.log(&quot;loaded&quot;)
  5. }

as src use imageUrl

  1. &lt;Image className=&quot;object-contain&quot;
  2. src={imageUrl}
  3. alt=&quot;Image&quot;
  4. fill
  5. onLoad={onImageLoad}
  6. priority
  7. style={{ display: loading ? &quot;none&quot; : &quot;block&quot; }}
  8. /&gt;

huangapple
  • 本文由 发表于 2023年6月1日 03:12:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76376601.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定