'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 |