我需要动态了解图像的宽度和高度,所以我使用了Image对象和onload事件函数。加载完所有图像后,我的组件应该重新呈现,并将高度和宽度值传递给子组件(<PhotoGallery />)。
这是我的解决方案。
import React, { useState, useRef } from "react";
import PhotoGallery from "react-photo-gallery";
import Lightbox from "react-image-lightbox";
import { makeStyles, createStyles, Theme, Grid, Button } from "@material-ui/core";
import { PhotoSharp } from "@material-ui/icons";
type Props = {
photoSrc: string[];
};
type PhotoGalleryImageType = {
src: string;
width: number;
height: number;
};
export default function ProjectGallery(props: Props) {
const [isLoading, setIsLoading] = useState(true);
const images = useRef<PhotoGalleryImageType[]>([]);
props.photoSrcSet.forEach((src) => {
var photo = new Image();
photo.src = src;
photo.onload = () => {
if (!images.current.some((v) => v.src === src)) {
images.current.push({ src: src, width: photo.naturalWidth, height: photo.naturalHeight });
}
if (images.current.length === props.photoSrcSet.length) {
setIsLoading(false);
}
};
});
if (isLoading) {
return <div>"loading.."</div>;
}
return (
<Grid container justify="center" direction="column">
<Grid item>
<PhotoGallery photos={images.current} />
</Grid>
</Grid>
);
}但是,我认为应该有更好的方法,因为如果没有if (!images.current.some((v) => v.src === src))语句,镜像src就会有重复的值。
你有什么意见建议?
发布于 2020-07-23 10:16:21
首先,将加载部分包装在useEffect()中,以确保它只触发一次;否则,它将在每次更新时触发。
然后,我建议首先获取所有唯一的源代码,然后在循环中使用它来加载和检查。此外,我认为您需要为图像使用state而不是ref:
import React, { useEffect, useState, useRef } from "react";
import PhotoGallery from "react-photo-gallery";
import Lightbox from "react-image-lightbox";
import { makeStyles, createStyles, Theme, Grid, Button } from "@material-ui/core";
import { PhotoSharp } from "@material-ui/icons";
type Props = {
photoSrc: string[];
};
type PhotoGalleryImageType = {
src: string;
width: number;
height: number;
};
export default function ProjectGallery(props: Props) {
const [isLoading, setIsLoading] = useState(true);
const [images, setImages] = useState<PhotoGalleryImageType[]>([]);
useEffect(() => {
const sources = [...new Set(props.photoSrcSet)]; // Get unique values
let loaded = 0; // Initialise a counter
sources.forEach((src) => {
var photo = new Image();
photo.src = src;
photo.onload = () => {
// Add loaded image to array
images.push({ src: src, width: photo.naturalWidth, height: photo.naturalHeight });
// Update the state
setImages(images);
// Up the loaded counter and compare
if (++loaded === sources.length) {
setIsLoading(false);
}
};
});
}, []); // Empty dependency array to use it as a componentDidMount
if (isLoading) {
return <div>"loading.."</div>;
}
return (
<Grid container justify="center" direction="column">
<Grid item>
<PhotoGallery photos={images} />
</Grid>
</Grid>
);
}https://stackoverflow.com/questions/63045508
复制相似问题