反应:图像加载时显示加载微调器 [英] React: Show loading spinner while images load

查看:102
本文介绍了反应:图像加载时显示加载微调器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个React应用,可在useEffect中调用我的API,该API返回URL列表以用作imy图像src.

I have a React app which makes a call in useEffect to my API which returns a list of URLs to use as imy image srcs.

我正在使用react-loader-spinner来显示我的图像加载时正在加载的微调器组件.

I am using react-loader-spinner to show a loading spinner component while my images load.

我在useState中有一个loading变量来确定图像是否正在加载.

I have a loading variable in useState to determine whether the images are loading.

我想不通如何停止显示正在加载的微调器,并在图像全部加载后显示它们.

I can not figure out how to stop showing the loading spinner and show my images once they have all loaded.

这是我的代码:

Photos.jsx

import React, { useState, useEffect, Fragment } from 'react'
import Loader from 'react-loader-spinner';
import { getAllImages } from '../../services/media.service';
import Photo from '../common/Photo';

const Photos = () => {
  const [photos, setPhotos] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
      setLoading(true);
      getAllImages()
        .then(results => {
          setPhotos(results.data)
          console.log(results.data)
        })
        .catch(err =>{
          console.log(err)
        })
  }, [])

  const handleLoading = () => {
    setLoading(false)
  }

  return ( 
    <Fragment>
      <div className="photos">
          { loading ? 
            <Fragment>
              <Loader
                height="100"    
                width="100"
              />
              <div>Loading Joe's life...</div>
            </Fragment>
            :
            photos.map((photo, index) => (
                index !== photos.length - 1 ? 
                <Photo src={photo.src} key={photo.id} /> :
                <Photo src={photo.src} key={photo.id} handleLoad={handleLoading}/>
            ))
          }
      </div>
    </Fragment>
   );
}

export default Photos;

Photo.jsx

import React from 'react'

import './Photo.css';

const Photo = (props) => {
  return ( 
    <div className="photo">
      <img src={props.src} alt={props.alt} onLoad={props.handleLoad}/>
      <div className="caption">
        Photo caption
      </div>
    </div>
   );
}

export default Photo;

我尝试将onLoad用于我的最后一个项目,但是它永远不会被调用,因为由于仍然显示了微调框,因此loading从未设置回false.

I tried using onLoad for my last item but it will never get called because loading is never set back to false due to the spinner still being shown.

在此方面的一些帮助将不胜感激.谢谢

Some help on this would be greatly appreciated. Thanks

推荐答案

onLoad从未被调用的原因是,因为您从未在DOM中拥有图像,因此有条件地将display属性设置为none&,而不是有条件地渲染. ;阻止.

The reason why onLoad was never called, is because you never had the images in the DOM, so instead of conditionally rendering, conditionally set the display property to none & block.

下面是一个简单的示例,说明如何等待所有图像加载.

Below is a simple example of how you could wait for all images to load.

可以安全地假定文件大小最大的图像很可能是最后一次加载

Safe to assume the image with the largest file size would most likely be the last to load

当然不是!!,加载图像所需的时间并不总是局限于大小,缓存或服务器加载会影响这些.

Most certainly not!!, the time it takes for an image to load is not always down to size, caching, or server load can effect these.

const {useState, useEffect, useRef} = React;

const urls = [
  "https://placeimg.com/100/100/any&rnd=" + Math.random(),
  "https://placeimg.com/100/100/any&rnd=" + Math.random(),
  "https://placeimg.com/100/100/any&rnd=" + Math.random()
];

function Test() {
  const [loading, setLoading] = useState(true);
  const counter = useRef(0);
  const imageLoaded = () => {
    counter.current += 1;
    if (counter.current >= urls.length) {
      setLoading(false);
    }
  }
  return <React.Fragment>
    <div style={{display: loading ? "block" : "none"}}>
       Loading images,
    </div>
    <div style={{display: loading ? "none" : "block"}}>
      {urls.map(url => 
        <img 
          key={url}
          src={url}
          onLoad={imageLoaded}/>)}
    </div>
  </React.Fragment>;
}

ReactDOM.render(<React.Fragment>
  <Test/>
</React.Fragment>, document.querySelector('#mount'));

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="mount"></div>

这篇关于反应:图像加载时显示加载微调器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆