0

Delete functionality here when you click the delete icon

Hi, how do I implement a similar delete functionality as from the link above?

I have attached my code below for your guys' reference, I'm using a map method to grab the data from an array of an object which is then transferred to props.

App.js file

import logo from "./logo.svg";
import "./App.css";
import IndividualContact from "./Components/IndividualContact";
import ContactList from "./Components/ContactList";
import EditDetails from "./Components/EditDetails";
import { useState } from "react";

const CONTACT_DATA = [
  {
    id: 1,
    name: "Leanne Graham",
    username: "Bret",
    email: "[email protected]",
    address: {
      street: "Kulas Light",
      suite: "Apt. 556",
      city: "Gwenborough",
      zipcode: "92998-3874",
      geo: {
        lat: "-37.3159",
        lng: "81.1496",
      },
    },
    phone: "1-770-736-8031 x56442",
    website: "hildegard.org",
    company: {
      name: "Romaguera-Crona",
      catchPhrase: "Multi-layered client-server neural-net",
      bs: "harness real-time e-markets",
    },
  },
  {
    id: 2,
    name: "Ervin Howell",
    username: "Antonette",
    email: "[email protected]",
    address: {
      street: "Victor Plains",
      suite: "Suite 879",
      city: "Wisokyburgh",
      zipcode: "90566-7771",
      geo: {
        lat: "-43.9509",
        lng: "-34.4618",
      },
    },
    phone: "010-692-6593 x09125",
    website: "anastasia.net",
    company: {
      name: "Deckow-Crist",
      catchPhrase: "Proactive didactic contingency",
      bs: "synergize scalable supply-chains",
    },
  },
  {
    id: 3,
    name: "Clementine Bauch",
    username: "Samantha",
    email: "[email protected]",
    address: {
      street: "Douglas Extension",
      suite: "Suite 847",
      city: "McKenziehaven",
      zipcode: "59590-4157",
      geo: {
        lat: "-68.6102",
        lng: "-47.0653",
      },
    },
    phone: "1-463-123-4447",
    website: "ramiro.info",
    company: {
      name: "Romaguera-Jacobson",
      catchPhrase: "Face to face bifurcated interface",
      bs: "e-enable strategic applications",
    },
  },
  {
    id: 4,
    name: "Patricia Lebsack",
    username: "Karianne",
    email: "[email protected]",
    address: {
      street: "Hoeger Mall",
      suite: "Apt. 692",
      city: "South Elvis",
      zipcode: "53919-4257",
      geo: {
        lat: "29.4572",
        lng: "-164.2990",
      },
    },
    phone: "493-170-9623 x156",
    website: "kale.biz",
    company: {
      name: "Robel-Corkery",
      catchPhrase: "Multi-tiered zero tolerance productivity",
      bs: "transition cutting-edge web services",
    },
  },
  {
    id: 5,
    name: "Chelsey Dietrich",
    username: "Kamren",
    email: "[email protected]",
    address: {
      street: "Skiles Walks",
      suite: "Suite 351",
      city: "Roscoeview",
      zipcode: "33263",
      geo: {
        lat: "-31.8129",
        lng: "62.5342",
      },
    },
    phone: "(254)954-1289",
    website: "demarco.info",
    company: {
      name: "Keebler LLC",
      catchPhrase: "User-centric fault-tolerant solution",
      bs: "revolutionize end-to-end systems",
    },
  },
  {
    id: 6,
    name: "Mrs. Dennis Schulist",
    username: "Leopoldo_Corkery",
    email: "[email protected]",
    address: {
      street: "Norberto Crossing",
      suite: "Apt. 950",
      city: "South Christy",
      zipcode: "23505-1337",
      geo: {
        lat: "-71.4197",
        lng: "71.7478",
      },
    },
    phone: "1-477-935-8478 x6430",
    website: "ola.org",
    company: {
      name: "Considine-Lockman",
      catchPhrase: "Synchronised bottom-line interface",
      bs: "e-enable innovative applications",
    },
  },
  {
    id: 7,
    name: "Kurtis Weissnat",
    username: "Elwyn.Skiles",
    email: "[email protected]",
    address: {
      street: "Rex Trail",
      suite: "Suite 280",
      city: "Howemouth",
      zipcode: "58804-1099",
      geo: {
        lat: "24.8918",
        lng: "21.8984",
      },
    },
    phone: "210.067.6132",
    website: "elvis.io",
    company: {
      name: "Johns Group",
      catchPhrase: "Configurable multimedia task-force",
      bs: "generate enterprise e-tailers",
    },
  },
  {
    id: 8,
    name: "Nicholas Runolfsdottir V",
    username: "Maxime_Nienow",
    email: "[email protected]",
    address: {
      street: "Ellsworth Summit",
      suite: "Suite 729",
      city: "Aliyaview",
      zipcode: "45169",
      geo: {
        lat: "-14.3990",
        lng: "-120.7677",
      },
    },
    phone: "586.493.6943 x140",
    website: "jacynthe.com",
    company: {
      name: "Abernathy Group",
      catchPhrase: "Implemented secondary concept",
      bs: "e-enable extensible e-tailers",
    },
  },
  {
    id: 9,
    name: "Glenna Reichert",
    username: "Delphine",
    email: "[email protected]",
    address: {
      street: "Dayna Park",
      suite: "Suite 449",
      city: "Bartholomebury",
      zipcode: "76495-3109",
      geo: {
        lat: "24.6463",
        lng: "-168.8889",
      },
    },
    phone: "(775)976-6794 x41206",
    website: "conrad.com",
    company: {
      name: "Yost and Sons",
      catchPhrase: "Switchable contextually-based project",
      bs: "aggregate real-time technologies",
    },
  },
  {
    id: 10,
    name: "Clementina DuBuque",
    username: "Moriah.Stanton",
    email: "[email protected]",
    address: {
      street: "Kattie Turnpike",
      suite: "Suite 198",
      city: "Lebsackbury",
      zipcode: "31428-2261",
      geo: {
        lat: "-38.2386",
        lng: "57.2232",
      },
    },
    phone: "024-648-3804",
    website: "ambrose.net",
    company: {
      name: "Hoeger LLC",
      catchPhrase: "Centralized empowering task-force",
      bs: "target end-to-end models",
    },
  },
];

function App() {
  const [showEditDetails, setShowEditDetails] = useState(false);

  const showEditHandlder = () =>{
    setShowEditDetails(true);
  }

  const closeEditHandlder = () => {
    setShowEditDetails(false);
  }
  return (
    <div className="App">
      {showEditDetails && (
        <EditDetails onClose={closeEditHandlder} contactData={CONTACT_DATA}></EditDetails>
      )}
      <ContactList onShow={showEditHandlder}  contactData={CONTACT_DATA}></ContactList>
    </div>
  );
}

export default App;

ContactList.js file

import React from 'react'
import IndividualContact from './IndividualContact'

export default function ContactList(props) {
  return (
    <div className="row g-4">

        {props.contactData.map((x) => (
        <IndividualContact 
        onShow={props.onShow}
        name={x.name}
        email={x.email}
        website={x.website}
        phone={x.phone}
        username={x.username}
        ></IndividualContact>

        ))}
    </div>
  )
}

IndividualContact.js file

import React from "react";
import { useState } from "react";
import "./IndividualContact.css";
import {
  MailOutlined,
  PhoneOutlined,
  GlobalOutlined,
  HeartOutlined,
  EditOutlined,
  DeleteOutlined,
  HeartFilled,
} from "@ant-design/icons";

export default function IndividualContactRow(props) {
  const [ifLiked, setIfLiked] = useState(false);
  const clickHandler = () => {
    setIfLiked(!ifLiked);
  };
  return (
    <div className=" col-xs-12 col-sm-12 col-md-4 col-lg-4 col-xl-3 col-3">
      <div className="container-test">
        <div className="body-image">
          <img
            src={`https://avatars.dicebear.com/v2/avataaars/${props.username}.svg?options[mood][]=happy`}
          ></img>
        </div>
        <div className="body-content">
          <h3>{props.name}</h3>
          <div className="d-flex flex-row">
            <MailOutlined style={{ fontSize: "18px", height: "26px" }} />
            <p>{props.email}</p>
          </div>
          <div className="d-flex flex-row">
            <PhoneOutlined style={{ fontSize: "18px", height: "26px" }} />
            <p>{props.phone}</p>
          </div>
          <div className="d-flex flex-row">
            <GlobalOutlined style={{ fontSize: "18px", height: "26px" }} />
            <p>{  `http://${props.website}`}</p>
          </div>
        </div>
        <ul className="body-actions">
          <li>
            <button onClick={clickHandler}>
              {ifLiked && <HeartFilled style={{ color: "red", fontSize: "20px" }}></HeartFilled>}
              {!ifLiked && (
                <HeartOutlined style={{ color: "red", fontSize: "20px" }} />
              )}{" "}
            </button>
          </li>

          <li>
            <button>
              {" "}
              <EditOutlined onClick={props.onShow} style={{ fontSize: "20px" }}></EditOutlined>
            </button>
          </li>

          <li>
            <button>
              {" "}
              <DeleteOutlined style={{ fontSize: "20px" }}></DeleteOutlined>
            </button>
          </li>
        </ul>
      </div>
    </div>
  );
}
3
  • 2
    Make the contact data a state array instead of passing the constant. Then on a delete button click, use filter() to create a copy of the array without the deleted element and set that as the new state array. Commented May 30, 2022 at 11:15
  • @ChrisG but how do I pass that which specific item needs to be deleted? Commented May 30, 2022 at 11:30
  • 1
    You use the id of the person, and pass it along to the delete handler function. Commented May 30, 2022 at 11:34

1 Answer 1

1

In App.js, create a local state which holds the list of users

const [contacts, setContacts] = useState(CONTACT_DATA);

Also create a method in App.js for deleting the data which will accept contact id as argument.

const deleteContact = (id) => {
   const tmpContacts = contacts.filter((contact) => contact.id != id);
   setContacts([...tmpContacts]);
}

Now instead of passing CONTACT_DATA as the prop in ContactList component, pass the contacts state variable. Also pass the newly created method deleteContact.

<ContactList onShow={showEditHandlder}  contactData={contacts} onDelete={deleteContact}></ContactList>

Now in ContactList component, pass this to IndividualContact component

<IndividualContact 
        onShow={props.onShow}
        name={x.name}
        email={x.email}
        website={x.website}
        phone={x.phone}
        username={x.username}
        onDelete={props.onDelete}
        ></IndividualContact>

Finally, hook this onDelete method to the delete button in Individual contact component.

<button onClick={(e) => props.onDelete(props.id)}>
   <DeleteOutlined style={{ fontSize: "20px" }}></DeleteOutlined>
</button>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot man, coincidentally I thought of the same solution but you structured the entire thing for me, much appreciated!
setContacts([...tmpContacts]); is not necessary, you can use setContacts(tmpContacts); instead (it's already a shallow copy)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.