带微调器的材质 UI CardMedia 图像

MaterialUI CardMedia Image with spinner

以下组件完美运行文件。在图像加载之前,我想显示一个微调器。我该怎么做?

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import Image from 'material-ui-image';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';

/**
 * Media is a Card, with an image / video and a caption. url of the media is hidden from the user,
 * but the user can click it to open it in a new browser
 */

const useStyles = makeStyles({
    card: {
        margin: '0.5rem',
        maxWidth: '25%'
    }
});

const Media = ({ url, caption }: any) => {
    const classes = useStyles();
    return (
        <Card className={classes.card}>
            <CardActionArea>
                <CardMedia component="img" alt={caption} height="140" image={url} title={caption} />
                <CardContent>
                    <Typography variant="body2">{caption}</Typography>
                </CardContent>
            </CardActionArea>
        </Card>
    );
};

export default Media;

Material-UI CardMedia component 将图像显示为背景图像,因此您将无法访问 DOM [=15] 上可用的 onLoad 属性 =] 标签。您可以选择使用 <img>,如下所示:

给你添加进口:

import CircularProgress from '@material-ui/core/CircularProgress';

添加到您的样式中:

  media: {
    width: '100%',
    height: 140,
  },
  progress: {
    # center spinner
  }

将状态和 onLoad 处理程序添加到您的组件:

  const [loaded, setLoaded] = React.useState(false);

  function handleImageLoad() {
    setLoaded(true);
  }

将您的 CardMedia 替换为:

  {loaded ? (
  <img
    className={classes.media}
    src={url}
    alt={caption}
    onLoad={handleImageLoad}
  />
  ) : (
  <div className={classes.progress}>
    <CircularProgress color="secondary" />
  </div>
  )}

无论是否加载图像,都应加载图像组件。我们无法通过将组件的高度设置为 0 然后在加载图像后将图像组件的高度设置为所需高度来在屏幕上显示图像组件。

然后,可以使用状态来跟踪图像是否已加载。

import React, { useState } from 'react';

// Image component with loading state
export default Image = () => {
  const [hasImageLoaded, setHasImageLoaded] = useState(false);

  return (
   <>
     <img src={src} onLoad={() => setHasImageLoaded(true)} className={`${!hasImageLoaded && height-0}`} />
     { !hasImageLoaded && <div> Loading... </div> }
   </>
  );
}

.height-0 {
  height: 0;
}

Ps。此代码可以根据您的用途进行更改。代码完成考虑一般用途