【问题标题】:React: Show loading spinner while images load反应:在图像加载时显示加载微调器
【发布时间】:2019-11-16 01:21:10
【问题描述】:

我有一个 React 应用程序,它在 useEffect 中调用我的 API,它返回一个 URL 列表以用作 imy 图像 src。

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

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

我不知道如何停止显示加载微调器并在全部加载后显示我的图像。

这是我的代码:

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,因为微调器仍在显示。

我们将不胜感激。谢谢

【问题讨论】:

  • 似乎onload 应该足以运行回调并设置状态?
  • @Sagivb.g - 永远无法到达
  • 好吧,我们需要查看Photo 的实现,以便尝试了解原因。顺便说一句,你为什么要调用它 handleLoading(false)
  • 不是因为Photo组件,而是loading永远不会变成false。
  • @Sagivb.g - 我添加了我的照片组件

标签: reactjs image spinner loading


【解决方案1】:

他们好吗?感谢您的帮助。我将它作为 Keith 解决方案,但它仍然不调用 onLoad 函数。它工作和触发 onLoad 的唯一方法是使用 img 父标签的可见性而不是显示。我希望它与显示道具一起使用

<div style={{visibility: loading ? "hidden" : "visible"}}>
  {urls.map(url => 
    <img 
      key={url}
      src={url}
      onLoad={imageLoaded}/>)}
</div>

【讨论】:

    【解决方案2】:

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

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

    可以假设文件最大的图片最有可能最后加载

    当然不是!!,加载图像所需的时间并不总是取决于大小、缓存或服务器负载会影响这些。

    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>

    【讨论】:

    • 只是另一个问题,是否可以使用条件渲染来解决这个问题?
    • @blueprintchris 可以,但工作量更大。你可以做的是使用fetch api 来加载图像。 developer.mozilla.org/en-US/docs/Web/API/Fetch_API
    • @blueprintchris 当然。试试:{ loading &&
      加载图片
      }
    • 您的回答帮助我在加载图像时实现了骨架。谢谢。
    • 美丽的????
    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多