ReactJS — динамически обновляемая форма с двойным вводом

#javascript #arrays #reactjs #state

#javascript #массивы #reactjs #состояние

Вопрос:

Я пытаюсь обновить форму с двойным вводом, каждый раз, когда пользователи нажимают кнопку «Добавить» и изменяют состояние со своими значениями, и я хочу, чтобы эти 2 входа были «подключены» к нему. Было бы более понятно, если бы я графически показал, что я пытаюсь сделать:

 [input] [second input] [remove button]
[input] [second input] [remove button]
[input] [second input] [remove button] ...
  

Намного проще, когда я пытаюсь динамически генерировать только один ввод, в настоящее время у меня даже нет полного кода, потому что я понятия не имею, как это сделать, но у меня есть некоторая часть, вот она:

состояние:

   stuff: {
            item: [],
            quantity: []
        },
  

и это был код для динамического добавления только одного поля ввода:

 // i mapped stuff because before i only had one array and like this-> stuff: []   
return this.state.stuff.map((element, index) => 
     <div key={index}>
        <input type="text" value={element||''} onChange={this.handleChange.bind(this, index)} />
        <input type='button' value='remove' onClick={this.removeInput.bind(this, index)}/>
     </div>          
 )

  handleChange(index, event) {
 let stuff = [...this.state.stuff];
 stuff[index] = event.target.value;
 this.setState({ stuff });
 }

     add(){
        this.setState(previousState => ({ stuff: [...previousState.stuff,'']}))
 }

     removeInput(index){
   let stuff = [...this.state.stuff];
   stuff.splice(index,1);
   this.setState({ stuff });
 }
  

Честно говоря, я просто пробовал каждую идею, и в функции add () я не могу полностью понять, как добавление '' в массив stuff заставляет код работать, если кто-нибудь объяснит это и даст мне решение для того, что я хочу сделать, я буду благодарен.

Ответ №1:

Я не могу полностью понять, как добавление «в stuff массив заставляет код работать

Если вы посмотрите на свой render() метод, вы увидите, this.state.stuff.map(...) таким образом, вы фактически сопоставляете каждое значение в stuff массиве с соответствующим вводом. Поэтому, если вы добавляете другое значение в stuff , компонент выполняет повторный запуск и сопоставляется новый ввод.


Теперь, чтобы добавить два ввода для каждой строки, вы могли бы сохранить два массива, но это затрудняет последующее управление данными. Вместо этого я бы использовал массив объектов, содержащий свойство item и quantity. Для этого внутри add() метода добавьте новые объекты:

   this.setState(({ stuff }) => ({ stuff: [...stuff, { item: "", quantity: 0 }));
  

Затем вам нужно изменить свое отображение внутри render() , чтобы отобразить эти объекты:

  this.state.stuff.map(({ item, quantity }, index) => (
  <div>
   Item: <input value={item} onChange={e => this.update(index, "item", e.target.value)} />
   Quantity: <input value={quantity} onChange={e => this.update(index, "quantity", e.target.value)} />
  </div>
 ));
  

Теперь единственное, что осталось, — это метод обновления, который принимает не только индекс, но и ключ для изменения:

  update(index, key, value) {
   this.setState(({ stuff }) => ({ stuff: stuff.map((it, i) => i === index ? { ...it, [key]: value }, it)) }));
 }