React Select mapping issue

2019-08-04 08:46发布

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

3条回答
姐就是有狂的资本
2楼-- · 2019-08-04 09:06

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;
  });
}
查看更多
何必那么认真
3楼-- · 2019-08-04 09:24

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];
            }
        }
    }
}
查看更多
我命由我不由天
4楼-- · 2019-08-04 09:25

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

查看更多
登录 后发表回答