I accidentally wrote some bad codes today and I would like to know why React shows me that result.
My code is something like this:
class Prova extends React.Component {
constructor (props) {
super(props);
this.state = {
people : [],
counter : 0,
person : {
name: "Michele",
surname: "Scavino"
}
}
}
addPeople = () => {
this.state.person["id"] = this.state.counter;
this.state.people = [
...this.state.people,
this.state.person
];
this.setState({counter: this.state.counter + 1});
}
render() {
return (
<div>
{
this.state.people?.map(el => {
return (
<div key={el.id}>
{el.name}
{el.surname}
{el.id}
</div>
)
})
}
<br />
<br />
<br />
<br />
<button onClick={this.addPeople}>Add person</button>
</div>
);
}
}
ReactDOM.render(
<Prova />,
document.getElementById('root')
);
The error here is that whenever I add a new person with the apposite button I copy the same ref of the same object in the array and when I go to change the ID of an element of the array, all of the ID of the elements of the array will change, using the spread operatore in this way. But the problem here is another. Whenever I add a new person also the displaying of new elements is very strange and I can't undestand why. If I click the button six times it should display to me 6 rows but actually it doesn't happen. It litterally freakout!!! I know that I'm trying to display a list of elements with the same keys but I can't realize why this trouble happen... Is there any expert who can answer my question appropiately or link me some resources to find out the answer to my question? I really suggest you to copy and run my code to see the bug with you eyes. Thank you!
You can't use an incremental id from within your component since it will be changed along with every render, Reactjs still miss your last rendering Id.
You will need to have a consistent id during renders:
One very popular solution is to use this UUID generator: https://www.npmjs.com/package/uuid
key in a map must be unique. You can use id to set a key:
{
this.state.people?.map((el) => {
return (
<div key={el.id}>
{el.name}
{el.surname}
{el.id}
</div>
);
});
}
And update addPeople like this:
addPeople = () => {
this.state.people = [...this.state.people, { ...this.state.person, id: this.state.counter }];
this.setState({ counter: this.state.counter + 1 });
};