Make a zoom of an specific image when clicked using map() in React.js

Viewed 1102

I am building a website to post photos. I made a grid system where it shows all images in small boxes, and I am trying to make a zoom box showing the image clicked. The images are rendered using map() from an image array list. However, I cannot show the image clicked.

This is the code.

import { useState, useEffect, Fragment } from "react";
import Aos from "aos";
import "aos/dist/aos.css";
import animations from "./data/animations";
import images from "./data/images";
import GridTransf from "./GridTransf";
import nature1 from "../assets/images/DSC00371.JPG";

function Pictures() {
  const [gridIsActive, setGridIsActive] = useState(false);
  const [cardViewIsActive, setCardViewIsActive] = useState(false);

  useEffect(() => {
    Aos.init({ duration: 1700 });
  }, []);

  const randChoice = (arr) => {
    const randIndex = Math.floor(Math.random() * arr.length);
    return arr[randIndex];
  };

  const transfToGrid = (e) => {
    setGridIsActive(!gridIsActive);
  };

  const imgIndex = images.id;

  console.log("Image Index " + imgIndex);

  const openCardView = (e) => {
    e.preventDefault();
    setCardViewIsActive(!cardViewIsActive);
  };

  return (
    <Fragment>
      <button onClick={transfToGrid}>
        <GridTransf />
      </button>
      {!gridIsActive ? (
        <div>
          <h1 className="title-no-grid">Nature 1</h1>
          <img className="picture-img" src={nature1} alt="first image" />
          {images.map((image) => (
            <div>
              <h1 className="title-no-grid">{image.title}</h1>
              <img
                className="picture-img"
                data-aos={randChoice(animations)}
                src={image.image}
                alt="nature1"
              />
            </div>
          ))}
        </div>
      ) : (
        <div className="grid-container">
          <div>
            <h1 className="title-with-grid">Nature 1</h1>
            <img
              className="grid-item picture-img"
              src={nature1}
              alt="first image"
            />
          </div>

          {images.map((image, index) => (
            <button onClick={openCardView}>
              <div className="grid-item">
                <h1 className="title-with-grid">{image.title}</h1>
                <img
                  className="grid-item picture-img"
                  data-aos={randChoice(animations)}
                  src={image.image}
                  alt="nature1"
                />
              </div>
            </button>
          ))}

          {cardViewIsActive && (
            <div className="backdrop" onClick={openCardView}>
              <div className="card-view">
                {images.map((image, index) => (
                  <div>
                    <img
                      className="grid-item picture-img"
                      src={image.image}
                      alt="nature1"
                    />
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      )}
    </Fragment>
  );
}

export default Pictures;

This is the list

import nature2 from "../../assets/images/DSC00376.JPG";
import nature3 from "../../assets/images/DSC00378.JPG";
import nature4 from "../../assets/images/DSC00390.JPG";
import animal1 from "../../assets/images/IMG_2437.JPG";

const images = [
  {
    id: 1,
    title: "Nature 2",
    image: nature2,
  },
  {
    id: 2,
    title: "Nature 3",
    image: nature3,
  },
  {
    id: 3,
    title: "Nature 4",
    image: nature4,
  },
  {
    id: 4,
    title: "Animal 1",
    image: animal1,
  },
];

export default images;

I guess the problem is that I cannot get the index to use it as a selector when clicked.

Thanks.

1 Answers

You can recreate handler

  const openCardView = (e, index) => {
    e.preventDefault();
    setCardViewIsActive(!cardViewIsActive);
    setSelectedIndex(index)
  };
....

{images.map((image, index) => (
    <button onClick={(e) => openCardView(e, index)}>
      <div className="grid-item">
        <h1 className="title-with-grid">{image.title}</h1>
        <img
          className="grid-item picture-img"
          data-aos={randChoice(animations)}
          src={image.image}
          alt="nature1"
        />
      </div>
    </button>
))}

you can use data attribute

  const openCardView = (e) => {
    e.preventDefault();
    setCardViewIsActive(!cardViewIsActive);
    setSelectedIndex(+e.currentTarget.dataset.index])
  };
....

{images.map((image, index) => (
    <button onClick={openCardView} data-index={index}>
      <div className="grid-item">
        <h1 className="title-with-grid">{image.title}</h1>
        <img
          className="grid-item picture-img"
          data-aos={randChoice(animations)}
          src={image.image}
          alt="nature1"
        />
      </div>
    </button>
))}
Related