react-image-lightbox: image not rendering

612 Views Asked by At

I have a situation with the react-image-lighbox package: once the Lightbox component is called, the desired image is not rendered unless there is some change to the code (whether on the IDE or simply pressing the prev/next image buttons), or I change the size of the viewport for example. Once a image from the map function is clicked, the Lighbox component is rendered but only the load spinner is shown.

It's the only part of the project where this kind of situation happens.

This is the code:

import React, { useEffect, useState } from "react";
import useAxios from "@/pages/hooks/useAxios";
import axios from "axios";
import Image from "next/image";
import { useRouter } from "next/router";
import Lightbox from "react-image-lightbox";
import "react-image-lightbox/style.css";

export default function ProjectPage() {
  const router = useRouter();
  const { id } = router.query;

  const APIURL = "http://localhost:5005";
  const [restOfImages, setRestOfImages] = useState<[]>([]);
  const [projectInfo, setProjectInfo] = useState<[]>([]);

  const [photoIndex, setPhotoIndex] = useState(-1);
  const [isOpen, setIsOpen] = useState(false);
  const [imagesLoaded, setImagesLoaded] = useState();

  const project = useAxios<any>({
    url: id != null ? `${APIURL}/api/project-nr?id=${id}` : null,
    initialValue: undefined,
    transform: ([project]) => {
      if (project == null) return undefined;
      setProjectInfo(project);
      return axios
        .get(`${APIURL}/images/?project=${project.name}`)
        .then((result) => {
          console.log(
            "Result.data",
            result.data.filter((image: { source: string | string[] }) =>
              image.source.includes(`img`)
            )
          );
          setRestOfImages(
            result.data.filter((image: { source: string | string[] }) =>
              image.source.includes(`img`)
            )
          );
        });
    },
  });

  useEffect(() => {
    console.log("photoIndex updated", photoIndex);
    if (photoIndex >= 0 && restOfImages) {
      console.log("photoIndex updated", photoIndex);
      console.log("nextIndex log", (photoIndex + 1) % restOfImages.length);
      console.log(
        "prevIndex log",
        (photoIndex + restOfImages.length - 1) % restOfImages.length
      );
    }
  }, [photoIndex, restOfImages]);

 const handleClick = (event: {
    target: { getAttribute: (arg0: string) => any };
  }) => {
    const index = event.target.getAttribute("data-index");
    if (index) {
      setPhotoIndex(parseInt(index));
      setIsOpen(true);
    }
  };

  const handleClose = () => {
    setPhotoIndex(-1);
    setIsOpen(false);
  };

return (
<section>
    <div>
      {restOfImages && (
        <>
          {restOfImages
            .filter((image) => image.source.includes("img"))
            .map((image, index) => (
              <Image
                src={`${APIURL}${image.source}`}
                alt=""
                width={1000}
                height={1000}
                onClick={handleClick}
                data-index={index} // Add data-index attribute
                key={image.id}
                className="rounded cursor-pointer "
              />
            ))}
          {isOpen && (
            <Lightbox
              mainSrc={`${APIURL}${restOfImages[photoIndex].source}`}
              nextSrc={`${APIURL}${
                restOfImages[(photoIndex + 1) % restOfImages.length]
                  .source
              }`}
              prevSrc={`${APIURL}${
                restOfImages[
                  (photoIndex + restOfImages.length - 1) %
                    restOfImages.length
                ].source
              }`}
              onCloseRequest={handleClose}
              onMovePrevRequest={() => {
                setPhotoIndex(
                  (photoIndex + restOfImages.length - 1) %
                    restOfImages.length
                );
                console.log("prevIndex Function called", photoIndex);
              }}
              onMoveNextRequest={() => {
                setPhotoIndex((photoIndex + 1) % restOfImages.length);
                console.log("nextIndex Function called", photoIndex);
              }}
              enableZoom={false}
              discourageDownloads={true}
              clickOutsideToClose={true}
            />
          )}
        </>
      )}
    </div>
</section>
);

It is a bit bizarre as I have console log the current, prev and next images, and the paths are being well passed. I also console log the prev and next index, both on the useEffect (to make sure everything is being set) and on the prop itself, and I have found that the "nextIndex log" or "prevIndex log" are always correct when compared to the "nextIndex Function called" or "prevIndex Function called", something I don't understand why.

1

There are 1 best solutions below

1
On

You can try to disable Strict mode. In your main.jsx disable <React.StrictMode>