'Weird return of data after splice and setstate
Here's simulate in codesandbox
https://codesandbox.io/embed/epic-nash-mxteu?fontsize=14&hidenavigation=1&theme=dark
I am having a weird behavior when I remove a row from the dynamic rows created.
I have removed the row with 2 b. As you can see the console log has the correct data while the UI showing wrong data. It means the function works well but somehow displaying incorrectly.
Anyone have idea why? Thanks in advance
Screenshots
Before remove row
After remove row
Source code
const [gavRows, setGAVRows] = useState([]);
const handleGAVAddRow = async () => {
try {
const item = {
gav_field: '',
gav_value: ''
};
setGAVRows([...gavRows, item]);
} catch (error) {
console.log('error', error)
}
};
const handleGAVRemoveSpecificRow = (idx) => {
console.log('idx', idx)
const tempRows = [...gavRows];
console.log('tempRows', tempRows)
tempRows.splice(idx, 1);
setGAVRows(tempRows)
};
const handleGAVChange = async (idx, e) => {
const { name, value } = e.target;
var tempRows = [...gavRows];
tempRows[idx][name] = value;
setGAVRows(tempRows)
};
<table className="customgav_section">
<tbody>
{
gavRows.map((item, idx) => {
console.log('map idx', idx, item)
return (
<tr key={idx}>
<td>
<Input type="text"
name="gav_field" id="gav_field"
value={gavRows[idx].field}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Input type="text"
name="gav_value" id="gav_value"
value={gavRows[idx].value}
onChange={(e) => handleGAVChange(idx, e)}
/>
</td>
<td>
<Button outline color="danger" onClick={() => handleGAVRemoveSpecificRow(idx)}><FaMinus /></Button>
</td>
</tr>)
})
}
</tbody>
</table>
Solution 1:[1]
Your problem is that you are using the index of the array as the key.
Read why that is bad: https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
A quick hack was assigning a random number as the key of each item in the gavRows and using that as the key of the element. See updated code: https://codesandbox.io/s/charming-bouman-03zn7
Also, the id of an element must be unique in the DOM so i removed those from the input elements.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Gabriele Petrioli |


