0

I'm trying to implement an add/remove fields from an array. I have my state hook setup, and should be able to click the add button to add a number to the emails array. It should then loop through the array of emails, and render an input for every value in the array. Each button looped over should have a remove button that removes it's specific value from the array.

I'm not able to add or remove elements:

const [emails, setEmails] = useState([]);

function RemoveEmail(i){
  const index = emails.indexOf(i);
  emails.splice(index, 1)
}

{emails.length > 0 && emails.map((email, i) => <p>{email}<button onClick={() => RemoveEmail(i)}>Remove</button></p>)}
<Button variant="outlined" size="small" onClick={() => setEmails(emails + 1)}>+ Add another</Button>

Update

Modified the add button so I can add values, but can't get the slice to remove a given element from the array:

<Button variant="outlined" size="small" onClick={() => setEmails([...emails, 1])}>+ Add another</Button>
Matt
  • 1,561
  • 5
  • 26
  • 61
  • Directly modifying state won't work; the state needs to be set w/ the updated value. This is core to how React works; it may be worth reading some tutorials. – Dave Newton Sep 01 '22 at 17:00
  • I'm just having a brain fart today. I need to be able to push a new value onto the emails array with `setEmails`, but blanking. – Matt Sep 01 '22 at 17:07
  • `setEmails([...emails, someNewEmail])` – Dave Newton Sep 01 '22 at 17:11
  • I figured out pushing an element to the array, but can't get the removal working. – Matt Sep 01 '22 at 17:11

1 Answers1

0

There are a couple of things which are incorrect in your code.

  1. Setting state directly using the old emails state.

setEmails(emails + 1) this is not the correct way to update the state for the new emails.

  1. Also removal of the emails is something I believe is incorrect as well.

For such a case when you need to implement adding a new value to the array and deleting it as well while managing the state, try to use a unique identifier.

I have created a working sandbox for you to refer here. Please tweak it as per your convenience.

On how to set state using the previous state value as well, refer to this link.

jateen
  • 642
  • 3
  • 13
  • Thank you so much! I'm seeing what you did here, but also noticed that the remove button isn't removing the right element. If you put an input element into each new row, and enter the number of that row, you'll see that it removes a different element. What would cause that? – Matt Sep 01 '22 at 17:26
  • I am sorry I am not able to understand what you are trying to do with the input element. – jateen Sep 01 '22 at 18:09
  • I'm saying that if you add a basic input element to the rows that are created, you'll see that the value removed isn't what's selected. Example here: https://codesandbox.io/s/using-usestate-forked-5m0ph9 – Matt Sep 01 '22 at 18:30
  • That's an entirely different issue Matt. You're simply using a bad value for key. You're using the index you get from map, which changes everytime you call map again. Since the index changes, it will always remove the last element. Just change your key to `emailId` (if that's an unique value) and you should be good. – Gabriel d'Agosto Sep 01 '22 at 19:43