I'm using react-select in my project and I'm using it within a map
like that:
renderItems() {
this.props.items.map(item => (
<Select
id="options"
value={this.state.optionSelected}
onChange={this.onChangeOption}
options={this.showOptions()}
/>
);
}
It show correctly all my options for all my items but now I can not get rid about the select...
Basically when I select an option on a single item, that option is changing for all items...
This is what i did so far:
onChangeOption(e) {
this.setState({ optionSelected: e.value });
}
How can I adjust it to change the option only on the one I wish to change it?
Thanks
You are using the same change handler for all of your select components and then set the same state value for all your select components. To deal with this either you need to separate your select components with a container component that handles their own state and change event or you need to give each select component a unique state value.
Example
renderItems() {
this.props.items.map(item => (
<Select
id="options"
value={this.state.optionSelected[item.id]}
onChange={(event) => this.onChangeOption(event, item.id)}
options={this.showOptions()}
/>
);
}
onChangeOption(event, itemId) {
this.setState((prevState) => {
const prevStateClone = Object.assign({}, prevState);
prevStateClone.optionSelected[itemId] = event.target.value;
return prevStateClone;
});
}
Instead of making optionSelected
string variable, make it as array in state.
Now do the following.
renderItems() {
this.props.items.map(item, index => (
<Select
id="options"
value={this.state.optionSelected[index]}
onChange={(selectedValue) => this.onChangeOption(selectedValue, index)}
options={this.showOptions()}
/>
);
}
onChangeOption(selectedValue, index) {
const optionSelected = this.state.optionSelected.slice() // slicing to get new copy of optionSelected instead of referencing to old one which causes mutation
optionSelected[index] = selectedValue
this.setState({optionSelected: optionSelected})
}
What you were doing is using a single variable to hold values of the select box. So if anyone changes, it will reflect all select box
Try cloning the object to a new object or if this optionSelected
is a class, you can implement a constructor that clones it for your like:
export class optionSelectedClass {
myfield = '';
constructor(fields){
this.myField = fields.myField;
}
}
or even
export class optionSelectedClass {
myfield = '';
constructor(fields){
for (let f in fields) {
if (!this[f]) {
this[f] = fields[f];
}
}
}
}