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

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

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:

&lt;div className=&quot;relative h-full m-auto&quot;&gt;
{loading ?
&lt;div&gt;
Loading Spinner goes here
&lt;/div&gt;
:
&lt;Image className=&quot;object-contain&quot;
src={image.url}
alt=&quot;Image&quot;
fill
onLoad={onImageLoad}
priority
/&gt;
}
&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:

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(&quot;loaded&quot;)
}

as src use imageUrl

   &lt;Image className=&quot;object-contain&quot;
src={imageUrl}
alt=&quot;Image&quot;
fill
onLoad={onImageLoad}
priority
style={{ display: loading ? &quot;none&quot; : &quot;block&quot; }}
/&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:

确定