J'ai un tableau d'objets. J'ai besoin d'ajouter une fonction pour supprimer un objet de mon tableau sans utiliser le mot-clé "this".
J'ai essayé d'utiliser updateList(list.slice(list.indexOf(e.target.name, 1)))
. Cela supprime tout sauf le dernier élément du tableau et je ne sais pas pourquoi.
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>
</>
)}
}
)
ATTENDU: l'élément cliqué sera supprimé de la liste.
RÉEL: La liste entière est supprimée, moins le dernier élément du tableau.
Merci d'avance pour toute contribution!
Tout d'abord, l'élément span
avec l'événement click doit avoir une propriété name
sinon, il n'y aura pas de nom à trouver dans le e.target
. Cela dit, e.target.name
Est réservé aux éléments de formulaire (entrée, sélection, etc.). Donc, pour exploiter la propriété name, vous devrez utiliser e.target.getAttribute("name")
De plus, étant donné que vous disposez d'un tableau d'objets, il ne serait pas efficace d'utiliser list.indexOf(e.target.name)
car il recherche un string
lorsque vous parcourez des objets. C'est comme dire de trouver "chien" dans [{}, {}, {}]
Enfin, array.slice()
renvoie un nouveau tableau commençant par l'élément à l'index que vous lui avez transmis. Donc, si vous cliquez sur le dernier élément, vous ne récupérerez que le dernier élément.
Essayez quelque chose comme ça à la place en utilisant .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(list.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);
Vous pouvez utiliser Array.filter pour le faire dans une ligne:
const handleRemoveItem = name => {
updateList(list.filter(item => item.name !== name))
}
Eta: vous devrez également passer le nom de votre article dans votre gestionnaire onClick:
{list.map(item => {
return (
<>
<span onClick={() =>handleRemoveItem(item.name)}>x </span>
<span>{item.name}</span>
</>
)}
Vous pouvez utiliser cette fonction pour supprimer un élément du tableau d'état de React sans muter l'état.
const handleRemoveItem = name => {
updateList(list => list.filter(item => item.name !== name));
}
Sandbox: https://codesandbox.io/s/ecstatic-goldwasser-76zop?fontsize=14
Je viens de faire face au même problème et corrigé en utilisant les réponses à cette question. Je mets ma réponse ici parce que j'ai dû utiliser plusieurs réponses pour y arriver.
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} => {
return (
<div key={idx}>
<span onClick={() =>handleRemoveItem(idx)}>x </span>
<span>{item.name}</span>
</div>
)}
}
)
Je pense que ce code fera l'affaire
let targetIndex = list.findIndex((each) => {each.name == e.target.name});
list.splice(targetIndex-1, 1);
Nous devons vérifier la valeur du nom à l'intérieur de l'objet, utilisez plutôt findIndex. puis coupez le début de l'objet de l'index cible à 1 tableau après l'index cible.
D'après votre commentaire, votre problème vient d'une autre partie.
Modifier cette section de vue
return (
<>
<span onClick={() => handleRemoveItem(item) }>x </span>
<span>{item.name}</span>
</>
)}
changer la fonction handleRemoveItem format
const handleRemoveItem = item => {
list.splice(list.indexOf(item)-1, 1)
updateList(list);
}