ReactJS-使用双重输入动态更新表单

时间:2019-03-30 10:50:40

标签: javascript arrays reactjs state

我试图用双倍输入更新表单,每次用户单击“添加”按钮并使用其值更改状态时,我希望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()函数中,如果有人解释了这一点并为我提供了所需的解决方案,那么我无法完全了解如何将''添加到东西数组中使代码工作我会很感激的。

1 个答案:

答案 0 :(得分:2)

  

我无法完全理解将''添加到stuff数组如何使代码正常工作

如果您研究render()方法,则会看到this.state.stuff.map(...),因此基本上可以将stuff数组中的每个值映射到相关的输入。因此,如果您向stuff添加另一个值,则组件会重新呈现,并且新的输入将被映射。


现在为每行添加两个输入,您可以保留两个数组,但是这使得以后管理数据更加困难。相反,我将使用包含项目和数量属性的对象数组。为此,在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)) }));
 }