reactjsonhover

add red cross delete functionality onhover in react


so i have data from api and mapped over them to present these images:

images

so i'm trying to do this project and now i'm basically stuck i'm not very good in react and css but i'm learning, and i want to do now is to add remove functionality. i have created a function that removes the picture from the data when i click on the image but what i want is when i hover over the image a red cross will appear and when i press the red cross i can trigger the function and delete the image

code:

import React,{useState,useEffect,useReducer} from 'react';
import axios from 'axios';
import {useForm} from 'react-hook-form';

const Data = () => {

    const [photo,setPhoto] = useState([])

    useEffect(() => {
        axios.get("https://jsonplaceholder.typicode.com/photos").then(
            result => {
                setPhoto(result.data)
            }
        )
    },[])

    const [Url,setUrl] = useState()
    const[photoId,setPhotoId] = useState()

    const showPicture = (url,id) => {
        setUrl(url)
        setPhotoId(id)
    }


    const handleDelete = id => {
        setUrl(null);
        setPhoto(prevState => prevState.filter(x => x.id !== id));
      };

      const {register,handleSubmit,errors} = useForm();
      const [links,setLinks] = useState({
          link:'',
          thumbnailLink:'',
          title:''
        })

        const onSubmit = (data) => {
            console.log(data)
        };

    return(
        <div>
            <div><img src={Url} onClick={() => handleDelete(photoId)}></img></div>
            <div>Posts</div>
            {/* <p>enter album Id to see the magic</p><input type="text" value={albumId} onChange={e => setAlbumId(e.target.value)}></input>
            <button type="button" onClick={handleClick}>Fetch Album</button> */}
            <div className="container">
            <div>{photo.slice(0,3).map(p => 
                 <div key={p.id}>
                    <img src={p.thumbnailUrl} thumbnailUrl={p.thumbnailUrl} onClick={() => showPicture(p.url,p.id)}></img>
                        <div>{p.title}</div>
                </div>
            )}</div>
            </div>
                <form onSubmit={handleSubmit(onSubmit)}>
                    <input type="url" placeholder="link" name="link" ref={register}/>
                    <input type="url" placeholder="thumbnail url" name="thumbnail" ref={register}/>
                    <input type="text" placeholder="title" name="title" ref={register}/>
                    <input type="submit" />
                </form>
        </div>

    )
}

export default Data;

Solution

  • Use css :hover to display button upon hover. Write a handler for delete and pass the index to it and use array splice to remove photo.

    Working demo (hover & close functionality)

    Delete Handler

    const handleImageDelete = id => {
        const updatedPhotos = [...photo];
        updatedPhotos.splice(id, 1);
        setPhoto(updatedPhotos);
      };
    

    JSX

    <div>
          <div className="container">
            <div>
              {photo.slice(0, 3).map((p, i) => (
                <div className="image" key={p.id}>
                  <img
                    alt=""
                    key={p.id}
                    src={p.thumbnailUrl}
                    thumbnailUrl={p.thumbnailUrl}
                    onClick={() => showPicture(p.url, p.id)}
                  />
                  <div
                    className="delete"
                    type="button"
                    onClick={() => handleImageDelete(i)}
                  >
                    X
                  </div>
                  <div>{p.title}</div>
                </div>
              ))}
            </div>
          </div>
        </div>
    

    Styles

    .image {
      position: relative;
      width: 150px;
      margin: 0px auto;
    }
    
    .image .delete {
      background-color: red;
      width: 20px;
      padding: 10px;
      color: white;
      display: none;
      cursor: pointer;
      position: absolute;
      top: 0;
      right: 0;
    }
    
    .image:hover .delete {
      display: block;
    }