How to delete an element from array in react?

Viewed 1481

I have two functions , one of them adds an item in array and the other one delete from that array using React JS (hooks).[Both are handler of click event].
What I have works incorrectly.
``id`` comes from ``contact.length`` and I deleted it with``contacts.splice(id, 1)``.
I dont have any idea why it has this problem.
it doesnt delete what would be clicked but a random one.
function handleAddRecord(nameValue, phoneValue) {
        setContacts([...contacts , {
            id : contacts.length,
            name : nameValue,
            phone : phoneValue
        }])
    }
    

    function handleDelete(id) {
        console.log("manager", id);
        const newContacts =  contacts.splice([id],1);
        setContacts([...newContacts]);
    }
5 Answers

One of the issue on the implementation is id generation keeping it array length could lead to issue as you delete and add elements there could be scenarios where there is same id for multiple items.

One of most widely used generator is uuid https://www.npmjs.com/package/uuid

Usage

const uuid = require("uuid");
uuid.v4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'

Now use this in your implementation

Add Operation:

const handleAddRecord = (nameValue, phoneValue) => {
  const newRecord = {
    id: uuid.v4(),  // This should be unique at all times
    name: nameValue,
    phone: phoneValue,
  };
  setContacts([...contacts, newRecord]);
};

Delete Operation:

Use filter rather than splice as for splice you'll need to find the index of the element with id. But with Filter it can be done is a single line

const handleDelete = (id) => {
  setContacts(contacts.filter(item => item.id !== id));
};

Here we're assuming that id is the index of the element to be removed.

The splice function returns the removed elements, thus is not useful to take its result. Instead, make a copy of the array first, then remove the undesired element:

function handleDelete(id) {
    console.log("manager", id);
    const newContacts =  [...contacts];
    newContacts.splice(id,1);
    setContacts(newContacts);
}

That's because splice alters the array itself.

More here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

Ok, id return index of current map? Follow this example:

const assoc = [...contacts];
assoc.splice(id, 1);
setContacts(assoc);

You can delete the item by finding its index from array.

For Example:

function handleDelete(id) {
   console.log("manager", id);
   const index = contacts.findIndex((x) => x.id === id);
   const newContacts = [
      ...contacts.splice(0, index),
      ...contacts.splice(index + 1),
   ];
   setContacts(newContacts);
}

You need undestand, every time when i'll remove a item from a array of a index, that this index has use unique key... When React remove a item 6 (a example) this is remove of array first, and when react re-render function react can delete another component, because a array exist key 6, wehn you have more 6 item from array... Understand?

Follow a example:

import React, { useState } from 'react';

function User(data) { // data is a array

  const [contacts, setContacts] = useState(data); // data return a list of contacts

  /* contacts result a array object and has the following attributes 
    [{
      name: 'Cael',
      tel_number: '+55 11 9999-999',
      e_mail: 'user@example.com',
  !   moment: "2021-06-15T05:09:42.475Z" // see this a date in ISO string
    }]
  */

  // about moment atribute:
  // this atribute result when use `new Date().toISOString()`
  // and this value is added in the moment that create a object in array list
  // It's mean that every time result a unique key

  const deleteFn = (val) => { // val result index of component and item array
    const assoc = [...contacts];
    assoc.splice(val, 1);
    setContacts(assoc);
  }

  return (
    <div>
      {!!contacts.length &&
      contacts.map((assoc, i) => { // variable i result in your id
        const { moment, name, e_mail, tel_number } = assoc; // moment use a unique key
        return (
          <li key={moment}> 
            <span>{name}</span>
            <span>{e_mail}</span>
            <span>{tel_number}</span>
            <button type="button" onClick={() => deleteFn(i)}>Delete</button>
          </li>
        );
      })}
    </div>
  );
}

export default User;

I hope, this helpfull you!

Related