Reputation: 1083
Fiddle Demo I'm trying to update the state array which contains an array of data objects.
State in constructor:
this.state = {
data: [
{ name: "Abc", age: 12 },
{ name: "Xyz", age: 11 }
]
}
Handlers:
handleName(idx, e){
const data = this.state.data.map((item, sidx) => {
if (idx !== sidx) return item;
return { ...item, name: e.target.value };
});
this.setState({ data: data });
}
handleAge(index, e){
const data = this.state.data.map((item, sidx) => {
if (idx !== sidx) return item;
return { ...item, age: e.target.value };
});
this.setState({ data: data });
}
Render Method :
render() {
console.log('render');
const Input = () => this.state.data.map((item, index) =>{
return (
<div>
<input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
<input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
</div>
);
});
return (
<div>
<Input/>
</div>
)
}
}
I know in every keystroke the render method is refreshing the dom, is something wrong with my rendering elements. Any suggestions ?
Upvotes: 0
Views: 97
Reputation: 281626
While returning element from within the map you must have a key assigned to them otherwise a new instance of it will be created always on a new render. Also you must not create a component within render
render() {
console.log('render');
return (
<div>
{this.state.data.map((item, index) =>{
return (
<div key={index}>
<input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
<input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
</div>
);
})}
</div>
)
}
}
Upvotes: 2
Reputation: 37755
Because on every re-render it is creating a new instance of the component woth values from state,
You need to take the function out of render or simply just use it like this
render() {
console.log('render');
return (
<div>
{this.state.data.map((item, index) =>{
return (
<div>
<input type="text" value={item.name} onChange={(e) => this.handleName(index, e)}/>
<input type="text" value={item.age} onChange={(e) => this.handleAge(index, e)}/>
</div>);})
}
</div>
)
}
}
Upvotes: 1