Why I have to click multiple time for selecting a image. Single click is not working

116 Views Asked by At

My App.Jsx is Given Below

import { useState } from 'react'
import imageGallery from './data/imageGallery';
import { Gallery } from './pages/Gallery';
import '../src/pages/Gallery.css';

const App = () => {
  const [images, setImages] = useState(imageGallery);

  const handleDelete = () => {
    const updatedImages = images.filter(
      (image) => !selectedImages.includes(image.id)
    );
    setImages(updatedImages);
    setSelectedImages([]);
  };

  return (
    <>
      <div className="gallery-wrap">
          <Gallery
            images={images}
            setImages={setImages}
          />
        </div>
    </>
  )
}

export default App

imageGallery.js

import image1 from '../assets/image-1.webp'
import image2 from '../assets/image-2.webp'
import image3 from '../assets/image-3.webp'
import image4 from '../assets/image-4.webp'
import image5 from '../assets/image-5.webp'
import image6 from '../assets/image-6.webp'
import image7 from '../assets/image-7.webp'
import image8 from '../assets/image-8.webp'
import image9 from '../assets/image-9.webp'
import image10 from '../assets/image-10.jpeg'
import image11 from '../assets/image-11.jpeg'

const imageGallery = [
    { id: 1, src: image1 },
    { id: 2, src: image2 },
    { id: 3, src: image3 },
    { id: 4, src: image4 },
    { id: 5, src: image5 },
    { id: 6, src: image6 },
    { id: 7, src: image7 },
    { id: 8, src: image8 },
    { id: 9, src: image9 },
    { id: 10, src: image10 },
    { id: 11, src: image11 },
  ];

  export default imageGallery;

Gallery.jsx

import React, { useState } from "react";
import { closestCenter, DndContext } from "@dnd-kit/core";
import {
  arrayMove,
  SortableContext,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { DraggableImage } from "../components/DraggableImage";

export const Gallery = ({images,setImages}) => {

  const [selectedImages, setSelectedImages] = useState([]);

  const handleImageClick = (id) => {
    setSelectedImages((prevSelectedImages) => {
      if (prevSelectedImages.includes(id)) {
        console.log("Image already selected, removing from selection");
        return prevSelectedImages.filter((imageId) => imageId !== id);
      } else {
        console.log("Image not selected, adding to selection");
        return [...prevSelectedImages, id];
      }
    });
  };
  const handleOnDragEnd = (event) => {
    const { active, over } = event;

    if (active?.id && over?.id && active.id !== over.id) {
      setImages((currentImages) => {
        const oldIndex = currentImages.findIndex(
          (image) => image.id === active.id
        );
        const newIndex = currentImages.findIndex(
          (image) => image.id === over.id
        );
        const updatedImages = arrayMove(currentImages, oldIndex, newIndex);

        return updatedImages.map((image, index) => ({
          ...image,
          selected: selectedImages.includes(image.id),
        }));
      });
    }
  };

  return (
    <>
      <DndContext
        collisionDetection={closestCenter}
        onDragEnd={handleOnDragEnd}
      >
        <SortableContext items={images} strategy={verticalListSortingStrategy}>
          {images.map(({ id, src }, index) => {
            return (
              <DraggableImage
                key={id}
                id={id}
                src={src}
                selectedImages={selectedImages}
                index={index}
                onImageClick={handleImageClick}
              />
            );
          })}
        </SortableContext>
      </DndContext>
    </>
  );
};

DraggableImage.jsx

import React from "react";
import { useSortable } from "@dnd-kit/sortable";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSquare, faCheckSquare } from "@fortawesome/free-solid-svg-icons";

export const DraggableImage = ({
  id,
  src,
  selectedImages,
  index,
  onImageClick,
}) => {
  const isSelected = selectedImages.includes(id);

  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({
      id,
      selected: isSelected,
    });

  const style = {
    transition,
    transform: transform ? `translate(${transform.x}px, ${transform.y}px)` : "",
  };

  const handleClick = () => {
    console.log("Image clicked with id:", id);
    console.log("isSelected before click:", isSelected);
    onImageClick(id);
    console.log("isSelected after click:", isSelected);
  };

  return (
    <>
      <div>
        <div
          ref={setNodeRef}
          style={style}
          {...attributes}
          {...listeners}
          className={`image-container ${index === 0 ? "featured-image" : ""} ${
            isSelected ? "selected" : ""
          }`}
          onClick={handleClick}
        >
          <div>
            <img src={src} alt={`${id}`} className="image" />
            <div className="selection-overlay">
              <FontAwesomeIcon
                icon={isSelected ? faCheckSquare : faSquare}
                className={`selection-box ${isSelected ? "selected" : ""}`}
              />
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

And Gallery.css

.gallery-wrap {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(3, 1fr);
    grid-gap: 20px;
    align-items: center;
    justify-items: center;
    max-width: 1400px;
    max-height: 100%;
    margin: 80px auto;
    padding: 20px;
  }
  
  .gallery-wrap .image-container {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    border: 5px solid #c9c6c6;
    cursor: pointer;
    max-width: 100%;
    max-height: 100%;
    transition: transform 0.3s, box-shadow 0.3s;
    border-radius: 20px;
    overflow: hidden;
  }
  
  .gallery-wrap .image-container img {
    max-width: 100%;
    max-height: 100%;
    object-fit: cover;
  }
  
  .gallery-wrap .featured-image {
    grid-column: span 2;
    grid-row: span 2;
  }
  
  .selection-box {
    position: absolute;
    top: 10px;
    left: 10px;
    color: white;
    /* padding: 6px 6px; */
    font-size: 40px;
  }
  
  .selection-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0;
    transition: opacity 0.2s;
    cursor: pointer;
    /* border-radius: 15px; */
  }
  
  .image-container:hover .selection-overlay,
  .selected .selection-overlay {
    opacity: 1;
    /* border-radius: 15px; */
  }
  .selected {
    color: blue;
  }

  

I have added images in grid view. I want to select image for delete. But my Issue is - when I click at the image nothing is happening. If I continuously clicking at the image then the image is selected. same for de selection. I need to solve this issue as soon as possible.

1

There are 1 best solutions below

2
On

handleImageClick function in the Gallery.jsx toggles the selection status of an image based on whether it's already selected or not.

There could be a few reasons for this behavior:-

1.Event Handling Issues: It's possible that there might be an issue with event handling. For example, if there are multiple elements with the same id on the page, it could cause conflicts.

2.State Management: There could be an issue with how the selectedImages state is being updated. Make sure that setSelectedImages is working as expected.

3.Component Rerendering: If the component is rerendering frequently, it might reset the selection status. This could happen if there are parent components that re-render unnecessarily.

4.Other Interactions: If there are other event listeners or interactions on the page, they might interfere with the click event.