3

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]);
    }
9
  • Do you want to delete a specific value from array ? If yes then use array.indexOf() and then use array.splice() Commented Jun 15, 2021 at 4:10
  • Please add the code where you are calling handleDelete function Commented Jun 15, 2021 at 4:11
  • I think it should be contacts.splice(id - 1, 1) Commented Jun 15, 2021 at 4:11
  • @Mr_Green it cant be as it's just removing the last one so he might use just .pop() Commented Jun 15, 2021 at 4:13
  • @Sanmeet hmm I thought the same but checking again seems that is not the case. I think the below answers are correct but the id should be id - 1, IMO. Commented Jun 15, 2021 at 4:15

5 Answers 5

4

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));
};
Sign up to request clarification or add additional context in comments.

4 Comments

I think you'll remove everything but the element actually useless.
Sorry just Updated the answer use this setContacts(contacts.filter(item => item.id !== id));
@MojtabaSedighi try the updated one on the answer. that works
thanka alot @samridhgupta it works as I want.
1

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: '[email protected]',
  !   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!

Comments

0

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

3 Comments

Thanks for your help, it works but , When I start clicking delete from the first element from the top it works correct. and when I click random it has some problem for example it wouldnt be deleted or delete an other one but not which was clicked.
I think the problem is about how the "id" is chosen. Using the array length is not a reliable reference, and you should have a unique key to assign to every single element. Move to a progressive counter, or better to a pseudo-random id generator like this one: github.com/dylang/shortid
Thank you alot for your help I did use ' uuid' as it mentioned here and my problem was solved
0

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

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

2 Comments

Thanks for your help, it works but , When I start clicking delete from the first element from the top it works correct. and when I click random it has some problem for example it wouldnt be deleted or delete an other one but not which was clicked.
I can undestand with life cycle components, whrn yout use map every time use a key props, and, whrn you use pro index... result delete another component.. I will public 2 ways how to use here
0

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);
}

1 Comment

I think you'll remove everything but the element actually useless.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.