Reputation: 13
I'm kinda new to React and i try to figure out how to change the state of my object's. But when i change the state in my input field the field is rerenderd at the bottom.
How can i keep my input field on the same place as it's renders the first time.
class App extends Component {
state = {
persons: [{
id: 0,
name: ''
},{
id: 1,
name: ''
}]
}
changePersonNameHandler = event => {
const id = parseInt(event.target.id);
const newPersonName = event.target.value;
this.setState({
persons: [...this.state.persons.filter(i => i.id !== id),
{
id,
name: newPersonName,
}
]
})
}
render () {
const {persons} = this.state;
return (
<div>
<ul>
{persons.map((i, index) => (
<li key={i.id}>
<label>Name: </label>
<input id={i.id}
value={i.name}
onChange{this.changePersonNameHandler}/>
</li>
)
)}
</ul>
</div>
)
}
}
Upvotes: 1
Views: 4257
Reputation: 4987
filter
removes an item and you lose its position. To modify an item and keep its place in the array use map
.
Also it is better not rely on this.state
to get a new value for setState
. You should use setState(oldState => newState)
instead.
changePersonNameHandler = event => {
const id = parseInt(event.target.id);
const newPersonName = event.target.value;
this.setState(old => {
const persons = old.persons.map(
person => person.id !== id ? person : {id, name: newPersonName}
);
return {persons};
})
}
Upvotes: 2
Reputation: 1114
Each time you're doing a change, you put the edited person at the end of the array in your handleChange method.
Just invert the edited one and the existing ones in setState and it will do the trick.
this.setState({
persons: [{
id,
name: newPersonName,
},
...this.state.persons.filter(i => i.id !== id)
]
})
}
=
sign after onChange
in the code you gave but I guess in your local code it's ok.Upvotes: 1