Reputation: 2619
I have many of the same component render on one page, my user can add more of the same child components if they want. When they choose the date within the form element of the child component I only want to change the date of the child component they selected. At the moment it changes the date for all the child components on the screen, can anyone see where I am going wrong?
class ParentFixturesComponent extends Component {
constructor() {
super();
this.state = {
numChildren: 0,
startDate: moment(),
id: uuid()
};
}
changeDate(newDate) {
this.setState({
startDate: newDate
});
}
onAddMatch() {
this.setState({
numChildren: this.state.numChildren + 1
});
}
render() {
const children = [];
for (let i = 0; i < this.state.numChildren; i += 1) {
children.push(<SingleMatchForm startDate={this.state.startDate}
key={this.state.id}
changeDate={this.changeDate.bind(this)}
/>)
}
return (
<Fixtures addMatch={this.onAddMatch.bind(this)}>
{children}
</Fixtures>
);
}
}
export default ParentFixturesComponent;
Child component
class SingleMatchForm extends Component {
handleChange(params) {
this.props.changeDate(params);
}
render() {
return (
<div className="row">
<div key={this.props.id} className="form-group">
<label className="control-label col-md-2">New Match</label>
<div className="col-md-6">
<DatePicker
selected={this.props.startDate}
onChange={this.handleChange.bind(this)}/>
<div className="section-divider mb40" id="spy1"> </div>
</div>
</div>
</div>
);
}
}
export default SingleMatchForm;
Upvotes: 1
Views: 1697
Reputation: 104369
Reason is, you are using single state
variable to save the date value of all the child components, if you update that single state
value it will affect all the components. To solve this problem use an array
instead of single value.
Like this:
this.state = {
numChildren: 0,
startDate: [], //array
id: uuid()
};
Now use each value of this array
for each child component and bind the index in onChange method to update the specific value, like this:
children.push(<SingleMatchForm startDate={this.state.startDate[i] || moment()}
key={this.state.id}
changeDate={this.changeDate.bind(this, i)}
/>)
And inside onChange method update the specific value not all the value:
changeDate(i, newDate) {
let startDate = this.state.startDate.slice();
startDate[i] = newDate;
this.setState({
startDate
});
}
Upvotes: 1
Reputation: 696
I only want to change the date of the child component they selected.
Then the child Component should hold date
as its state, or Make the parent hold the dates in an array from all the child components.
Upvotes: 0