Реагировать на проблему выбора отображения

Я использую react-select в своем проекте и использую его в map подобном что:

renderItems() {
  this.props.items.map(item => (
    <Select
      id="options"
      value={this.state.optionSelected}
      onChange={this.onChangeOption}
      options={this.showOptions()}
    />
  );
}

Он правильно показывает все мои параметры для всех моих предметов, но теперь я не могу избавиться от выбора...

В основном, когда я выбираю параметр для одного элемента, этот параметр меняется для всех элементов...

Это то, что я сделал до сих пор:

onChangeOption(e) {
  this.setState({ optionSelected: e.value });
}

Как я могу настроить его, чтобы изменить параметр только на тот, который я хочу изменить?

Спасибо


person Ayeye Brazo    schedule 28.09.2017    source источник
comment
это меняет все, потому что все они зависят от одной переменной.   -  person Jan Ciołek    schedule 28.09.2017
comment
Это нормально... но как я могу это решить?   -  person Ayeye Brazo    schedule 28.09.2017
comment
Сделайте так, чтобы каждый из них зависел от разных переменных   -  person Jan Ciołek    schedule 28.09.2017
comment
Если у вас есть уникальный идентификатор для каждого элемента (например, id), вы можете обновить состояние конкретного элемента, а не всех из них.   -  person Shota    schedule 28.09.2017
comment
Поскольку он динамический, не могли бы вы ответить на вопрос, показав его пример?   -  person Ayeye Brazo    schedule 28.09.2017


Ответы (3)


Вы используете один и тот же обработчик изменений для всех выбранных вами компонентов, а затем устанавливаете одно и то же значение состояния для всех выбранных вами компонентов. Чтобы справиться с этим, вам нужно либо разделить ваши выбранные компоненты с компонентом-контейнером, который обрабатывает свое собственное состояние и событие изменения, либо вам нужно дать каждому выбранному компоненту уникальное значение состояния.

Пример

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;
  });
}
person bennygenel    schedule 28.09.2017

Вместо создания строковой переменной optionSelected сделайте ее массивом в состоянии. Теперь сделайте следующее.

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})
}

То, что вы делали, это использование одной переменной для хранения значений поля выбора. Поэтому, если кто-то изменится, он будет отражать все поля выбора

person Mahesh Bhuva    schedule 28.09.2017

Попробуйте клонировать объект в новый объект или, если этот optionSelected является классом, вы можете реализовать конструктор, который клонирует его по своему усмотрению:

export class optionSelectedClass {
    myfield = '';

    constructor(fields){
        this.myField = fields.myField;
    }
}

или даже

export class optionSelectedClass {
    myfield = '';

    constructor(fields){
        for (let f in fields) {
            if (!this[f]) {
                this[f] = fields[f];
            }
        }
    }
}
person assisrMatheus    schedule 28.09.2017