Reputation: 3176
I am trying to have a list of table fields which can be added and removed at any time.
As soon as I click delete any element in the middle(except the last one), it deletes all items underneath it
Code is here
I am not sure what is it that's doing wrong, it removes all the elements, even if I try to delete a specific one.
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
const ListComponent = ({ remove, id }) => {
return (
<tr>
<td>
<input />
</td>
<td><button onClick={() => remove(id)}>Delete</button></td>
</tr>
)
}
const App = () => {
const [array, setArray] = useState([]);
const remove = (itemId) => {
setArray(array.filter(each => each.id !== itemId))
}
const addListComponent = () => {
let id = uuidv4();
setArray(oldArray => [...oldArray, {
id,
jsx: <ListComponent key={id} id={id} remove={remove}/>
}])
}
return (
<div>
<button onClick={addListComponent}>Add ListComponent</button>
{array.length > 0 && array.map(each => each.jsx)}
</div>
)
}
export default App;
Upvotes: 0
Views: 47
Reputation: 10382
the issue is everytime you create a new element a new remove
function is created with reference to that current state in time. When you create an element, you create a jsx with a remove
pointing to that array
reference specific in time.
You could fix that changing your remove
function to something like:
const remove = (itemId) => {
setArray(prevArr => prevArr.filter(each => each.id !== itemId))
}
which would ensure that you will always have the correct reference to the current state.
Although that solves the issue, I would suggest to follow the guidelines and only store the necessary information at your state, and pass it to JSX at render when you map:
const App = () => {
const [array, setArray] = useState([]);
const remove = (itemId) => {
setArray(array.filter(each => each.id !== itemId))
}
const addListComponent = () => {
let id = uuidv4();
setArray(oldArray => [...oldArray, { id }])
}
return (
<div>
<button onClick={addListComponent}>Add ListComponent</button>
{array.length > 0 && array.map(({ id }) => <ListComponent key={id} id={id} remove={remove}/>)}
</div>
)
}
Upvotes: 2