当所有图像对象都加载到React中时,如何重新渲染组件



我需要动态地知道图像的宽度和高度,所以我使用了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))语句,那么image-src就会有重复的值。

你有什么建议吗?

首先将加载部件封装在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>
   );
}

相关内容

  • 没有找到相关文章

最新更新