reactjs - Ta bort objekt från array med hjälp av hooks (useState)
Jag har en array av objekt. Jag behöver lägga till en funktion för att ta bort ett objekt från min array utan att använda nyckelordet "this".
Jag försökte använda updateList(list.slice(list.indexOf(e.target.name, 1))). Detta tar bort allt utom det sista objektet i arrayen och jag är inte säker på varför.
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }]
const [list, updateList] = useState(defaultList);
const handleRemoveItem = e => {
updateList(list.slice(list.indexOf(e.target.name, 1)))
}
return (
{list.map(item => {
return (
<>
<span onClick={handleRemoveItem}>x </span>
<span>{item.name}</span>
</>
)}
}
)
Förväntat beteende: Det klickade objektet kommer att tas bort från listan.
Aktuellt beteende: Hela listan tas bort, förutom det sista objektet i arrayen.
Svar #1
För det första behöver span-elementet med klickhändelsen ha en name-egenskap, annars kommer det inte finnas något namn att hitta inom e.target. Med det sagt är e.target.name reserverat för formelement (input, select, etc). Så för att faktiskt komma åt name-egenskapen måste du använda e.target.getAttribute("name")
Dessutom, eftersom du har ett fält med objekt, skulle det inte vara effektivt att använda list.indexOf(e.target.name) eftersom det letar efter en string när du itererar över objekt. Det är som att säga hitta "dog" inom [{}, {}, {}]
Slutligen returnerar array.slice() en ny matris som börjar med objektet på det index du skickade till den. Så om du klickade på det sista objektet skulle du bara få tillbaka det sista objektet.
Prova något liknande istället med .filter(): codesandbox
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const App = () => {
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }
];
const [list, updateList] = useState(defaultList);
const handleRemoveItem = (e) => {
const name = e.target.getAttribute("name")
updateList(l => l.filter(item => item.name !== name));
};
return (
<div>
{list.map(item => {
return (
<>
<span name={item.name} onClick={handleRemoveItem}>
x
</span>
<span>{item.name}</span>
</>
);
})}
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Svar #2
Du kan använda Array.filter för att göra detta i en enradare:
const handleRemoveItem = name => {
updateList(list.filter(item => item.name !== name))
}
Eta: du kommer också behöva skicka namnet på ditt objekt i din onClick-handler:
{list.map(item => {
return (
<>
<span onClick={() =>handleRemoveItem(item.name)}>x </span>
<span>{item.name}</span>
</>
)}
Svar #3
const defaultList = [
{ name: "ItemOne" },
{ name: "ItemTwo" },
{ name: "ItemThree" }
]
const [list, updateList] = useState(defaultList);
const handleRemoveItem = idx => {
// assigning the list to temp variable
const temp = [...list];
// removing the element using splice
temp.splice(idx, 1);
// updating the list
updateList(temp);
}
return (
{list.map((item, idx) => (
<div key={idx}>
<button onClick={() => handleRemoveItem(idx)}>x </button>
<span>{item.name}</span>
</div>
))}
)
