'How to delete an item from a list using input in form (React using states)?

I want to delete an object from an array using its name.

  const [formDataRemoval, setFormDataRemoval] = React.useState({
    name: "",
  });

When input changes, the following function detects it.


  function handleChangeRemoval(event) {
    setFormDataRemoval((prevFormDataRemoval) => {
      return {
        ...prevFormDataRemoval,
        [event.target.name]: event.target.value,
      };
    });
  }

When button "Remove Item" which is set in form, is clicked, the function removeItem() is run.

  function removeItem(event) {

    console.log("Remove item");
    event.preventDefault()
    setAllThingsArray({allThingsArray: this.state.allThingsArray.filter((thing) => 
        thing.name !== event.target.name
    )});
  }

data is read from json file which has following structure:

[
    {
        "key": 1,
        "img": "../images/stamp1.jpg",
        "name": "Stamp 1",
        "description": "Aeroplane",
        "rating": 5.0
    },
    {
        "key": 2,
        "img": "../images/stamp2.jpg",
        "name": "Stamp 2",
        "description": "Kustendje & czernawoda",
        "rating": 6.0
    },
    {
        "key": 3,
        "img": "../images/stamp3.jpg",
        "name": "Stamp 3",
        "description": "Koala",
        "rating": 7.0
    }
]
const [allThingsArray, setAllThingsArray] = React.useState(data);

  const allThingsElements = allThingsArray.map((st) => {
    return <Stamp key={st.key} st={st} />;
  });

However, when I click the button, nothing happens and nothing shows in the console. How to fix this?

PS. the whole component looks like this:

import React from "react";
import data from "../data";
import Stamp from "./Stamp";

export default function AddRemoveItem() {

  // ------------------------------ FORM
  const [formData, setFormData] = React.useState({
    img: "",
    name: "",
    description: "",
    rating: "",
  });

  const [formDataRemoval, setFormDataRemoval] = React.useState({
    name: "",
  });

  function handleChange(event) {
    setFormData((prevFormData) => {
      return {
        ...prevFormData,
        [event.target.name]: event.target.value,
      };
    });
  }

  function handleChangeRemoval(event) {
    setFormDataRemoval((prevFormDataRemoval) => {
      return {
        ...prevFormDataRemoval,
        [event.target.name]: event.target.value,
      };
    });
  }

  // ------------------------------- REMOVE ITEM

  function removeItem(event) {

    console.log("Remove item");
    event.preventDefault()
    setAllThingsArray({allThingsArray: this.state.allThingsArray.filter((thing) => 
        thing.name !== event.target.name
    )});
  }

  // ------------------------------- ADD ITEM

  const [thingsArray, setThingsArray] = React.useState({
    key: 4,
    img: "../images/stamp1.jpg",
    name: "Stamp 5",
    description: "AAAA",
    rating: 78.0,
  });

  function addItem(event) {
    
    console.log("Add item");
    event.preventDefault()
    const updatedThingsArray = { // add an updated object

      ...thingsArray, //this is an actual previous state
      key: thingsArray.key + 1,
      img: formData.img,
      name: formData.name,
      description: formData.description,
      rating: formData.rating,
    };

    setAllThingsArray((prevAllThingsArray) => [
      ...prevAllThingsArray,
      updatedThingsArray, //it's become a new object with your updated data
    ]);

    setThingsArray(updatedThingsArray); // update it back to thingsArray
  }

  const [allThingsArray, setAllThingsArray] = React.useState(data);

  const allThingsElements = allThingsArray.map((st) => {
    return <Stamp key={st.key} st={st} />;
  });

  return (
    <>
      <form id="form" onSubmit={addItem}>
        <input
          type="text"
          className="form--input"
          placeholder="Image"
          onChange={handleChange}
          name="img"
          value={formData.img}
        />
        <input
          type="text"
          className="form--input"
          placeholder="Stamp title"
          onChange={handleChange}
          name="name"
          value={formData.name}
        />
        <input
          type="text"
          className="form--input"
          placeholder="Description"
          onChange={handleChange}
          name="description"
          value={formData.description}
        />
        <input
          type="text"
          className="form--input"
          placeholder="Rating"
          onChange={handleChange}
          name="rating"
          value={formData.rating}
        />
        <button className="form--button">
          Add Stamp
        </button>
      </form>

      <section className="stamps-list">{allThingsElements}</section>
    
      <div className="form" onSubmit={removeItem}>
        <input 
            type="text" 
            className="form--input"
            placeholder="Stamp title"
            onChange={handleChangeRemoval}
            name="name"
            value={formDataRemoval.name}
        />   
        <button className="form--button">
          Remove Stamp
        </button>
      </div>

    </>
  );
}


Solution 1:[1]

div does not have onSubmit event and you also don't wrap a form element for those elements, that's why removeItem is not triggered as you expected.

From your logic, I can guess you're trying to remove an item that is a matched name with the input field value.

You can change onSubmit to onClick and move that event to button instead

<div className="form">
        <input 
            type="text" 
            className="form--input"
            placeholder="Stamp title"
            onChange={handleChangeRemoval}
            name="name"
            value={formDataRemoval.name}
        />   
        <button className="form--button" onClick={removeItem}>
          Remove Stamp
        </button>
      </div>

At the same time, you should align your logic in removeItem() by using formDataRemoval.name

  function removeItem(event) {
    event.preventDefault()
    
    //simplify your logic here
    setAllThingsArray(allThingsArray.filter((thing) => 
        thing.name !== formDataRemoval.name
    ));
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nick Vu