47 votes

Suppression d'un objet d'un tableau en utilisant des hooks (useState)

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 dans le tableau et je ne suis pas certain 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 ( 
            <>
            x 
            {item.name}

        )}
    }

)

PRÉVU: L'élément cliqué sera supprimé de la liste.
ACTUEL : La liste entière est supprimée, à l'exception du dernier élément dans le tableau.

Merci d'avance pour toute contribution!

49voto

Cool Guy Points 13411

Tout d'abord, l'élément span avec l'événement de clic doit avoir une propriété name sinon, il n'y aura pas de nom à trouver dans e.target. Cela dit, e.target.name est réservé aux éléments de formulaire (input, select, etc). Donc pour réellement accéder à la propriété name, vous devrez utiliser e.target.getAttribute("name")

De plus, parce que vous avez un tableau d'objets, il ne serait pas efficace d'utiliser list.indexOf(e.target.name) car cela recherche une chaîne de caractères lorsque vous itérez sur des objets. C'est comme dire trouvez "chien" dans [{}, {}, {}]

Enfin, array.slice() renvoie un nouveau tableau commençant par l'élément à l'index que vous lui avez passé. Donc si vous avez cliqué sur le dernier élément, vous n'obtiendrez que le dernier élément.

Essayez plutôt quelque chose comme ceci 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 (

      {list.map(item => {
        return (
          <>

              x

            {item.name}

        );
      })}

  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(, rootElement);

19voto

Will Jenkins Points 508

Vous pouvez utiliser Array.filter pour faire cela en une seule ligne :

const handleRemoveItem = name => {
    updateList(list.filter(item => item.name !== name))
}

Note : vous devrez également passer le nom de votre élément dans votre gestionnaire onClick :

{list.map(item => {
    return ( 
        <>
        handleRemoveItem(item.name)}>x 
        {item.name}

    )}

9voto

Dimi Mikadze Points 190

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

6voto

Mahesh Samudra Points 113

J'ai rencontré le même problème et je l'ai résolu en utilisant les réponses de cette question. Je poste ma réponse ici car j'ai dû utiliser plusieurs réponses pour y parvenir.

const defaultList = [
    { name: "ÉlémentUn" },
    { name: "ÉlémentDeux" },
    { name: "ÉlémentTrois" }
]

const [list, updateList] = useState(defaultList);

const handleRemoveItem = idx => {
    // assigner la liste à une variable temporaire
    const temp = [...list];

    // supprimer l'élément en utilisant splice
    temp.splice(idx, 1);

    // mettre à jour la liste
    updateList(temp);
}

return (
    {list.map((item, idx} => {
        return ( 

                handleRemoveItem(idx)}>x 
                {item.name}

        )}
    }

)

1voto

William Gunawan Points 738

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, donc utilisez findIndex à la place. Ensuite, découpez l'objet à partir de l'index cible jusqu'à 1 élément après l'index cible.

Codepen

D'après votre commentaire, votre problème vient d'une autre partie.

Changer cette section d'affichage

    return (
        <>
         handleRemoveItem(item)}>x 
        {item.name}

    )}

Changer le format de la fonction handleRemoveItem

const handleRemoveItem = item => {
    list.splice(list.indexOf(item)-1, 1)
    updateList(list);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X