react duplicated item when removed from useState

Viewed 266

I try to make a reservation app for my end year project. I don't know why I can add an item in the state but when I try to remove it and add it again it got duplicated. I made a lot of research but didn't find responses.

here the problem :

enter image description here

and here is my code :


    const [js, setJs] = useState([]);

    const addPlace = (target) => {
    let selectedPlace = document.getElementById(target.id);
    const temporary = js;

    const placeAjouteeASelection = {
      id: target.id,
      key: `${target.id} ${dateUtilisee} ${heureDebutUtilisee} ${heureFinUtilisee}`,
      nom: target.id.split('Place')[1],
      date: dateUtilisee,
      heureDebutUtilisee: heureDebutUtilisee,
      heureFinUtilisee: heureFinUtilisee,
    };

    switch (selectedPlace.getAttribute('fill')) {
      case couleurPlaceReservee:
        alert('place reservée !');
        break;
      case couleurPlaceSelectionnee:
        const toBeDeleted = selectedPlace.id;
        selectedPlace.setAttribute('fill', couleurPlaceDisponible);
        setJs(js.filter((item) => item.id !== toBeDeleted));
        break;
      case couleurPlaceDisponible:
        selectedPlace.setAttribute('fill', couleurPlaceSelectionnee);
        temporary.push(placeAjouteeASelection);
        setJs([...temporary]);
        break;
      default:
        selectedPlace.setAttribute('fill', couleurPlaceDisponible);
        break;
    }
    console.log('TEMPORARY', temporary);
  };

Thanks for your help.

EDIT:

Okay I tried your solution, but now when you remove an element from the array it remove everything, any idea ? I tried to use filter array.

Here a small gif and my code :

    switch (selectedPlace.getAttribute('fill')) {
  case couleurPlaceReservee:
    alert('place reservée !');
    break;
  case couleurPlaceSelectionnee:
    const toBeDeleted = selectedPlace.id;
    selectedPlace.setAttribute('fill', couleurPlaceDisponible);
    const list = js.filter((item) => item.id !== toBeDeleted);
    setJs(list);
    break;
  case couleurPlaceDisponible:
    selectedPlace.setAttribute('fill', couleurPlaceSelectionnee);
    setJs((prev) => {
      return [...prev, placeAjouteeASelection];
    });
    break;
  default:
    selectedPlace.setAttribute('fill', couleurPlaceDisponible);
    break;
}

into render function :

     {js &&
    js.map((a) => {
      return <li key={a.key}>{a.nom}</li>;
    })}

enter image description here

1 Answers

You should use the up-to-date state variable

case couleurPlaceDisponible:
        selectedPlace.setAttribute('fill', couleurPlaceSelectionnee);
        temporary.push(placeAjouteeASelection);
        setJs(temporary => {return [...temporary]});
        break;

case couleurPlaceSelectionnee:
        const toBeDeleted = selectedPlace.id;
        selectedPlace.setAttribute('fill', couleurPlaceDisponible);
        js.splice(toBeDeleted, 1);
        setJs([...js])
        break;
Related