React:在加载图像时显示加载微调器
React: Show loading spinner while images load
我有一个 React 应用程序,它在 useEffect
中调用我的 API,其中 returns 一个 URL 列表用作 imy 图像源。
我正在使用 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 的原因是因为您从未在 DOM 中拥有图像,因此不是有条件地渲染,而是有条件地将显示 属性 设置为 none &阻止。
下面是一个简单的示例,说明如何等待所有图像加载。
Safe to assume the image with the largest file size would most likely be the last to load
当然不是!!加载图像所需的时间并不总是取决于大小、缓存或服务器负载会影响这些。
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>
他们怎么样?谢谢你的帮忙。我把它作为 Keith 解决方案,但它仍然没有调用 onLoad 函数。它工作并触发 onLoad 的唯一方法是使用 img 父标签的可见性而不是显示。我希望它与展示道具一起使用
<div style={{visibility: loading ? "hidden" : "visible"}}>
{urls.map(url =>
<img
key={url}
src={url}
onLoad={imageLoaded}/>)}
</div>
我有一个 React 应用程序,它在 useEffect
中调用我的 API,其中 returns 一个 URL 列表用作 imy 图像源。
我正在使用 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 的原因是因为您从未在 DOM 中拥有图像,因此不是有条件地渲染,而是有条件地将显示 属性 设置为 none &阻止。
下面是一个简单的示例,说明如何等待所有图像加载。
Safe to assume the image with the largest file size would most likely be the last to load
当然不是!!加载图像所需的时间并不总是取决于大小、缓存或服务器负载会影响这些。
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>
他们怎么样?谢谢你的帮忙。我把它作为 Keith 解决方案,但它仍然没有调用 onLoad 函数。它工作并触发 onLoad 的唯一方法是使用 img 父标签的可见性而不是显示。我希望它与展示道具一起使用
<div style={{visibility: loading ? "hidden" : "visible"}}>
{urls.map(url =>
<img
key={url}
src={url}
onLoad={imageLoaded}/>)}
</div>