反应多输入(输入数组)不起作用

时间:2015-08-25 23:06:08

标签: reactjs

所以我试图用React渲染多个输入字段。 一切都很好,直到我删除一个项目。始终是最后一项"已删除"。如果你想尝试我的代码,写下" A"在输入字段1中," B" 2," C"在3中删除" B"。您会注意到您已删除" C"代替。

我为value尝试了defaultValueinput无效。我也试过给输入命名。我想我在这里错过了一个关键点。

有什么建议吗?

var MultiInput = React.createClass({
  getInitialState: function() {
    value = this.props.value
    // force at least one element
    if (!value || value == '') {
      value = [ null ]
    }

    return {
      value: value
    }
  },
  getDefaultProps: function() {
    return {
    }
  },
  add_more: function() {
    new_val = this.state.value.concat([])
    new_val.push(null)
    this.setState({ value: new_val })
  },
  remove_item: function(e, i) {
    new_state = this.state.value.concat([])
    new_state.splice(i,1)
    this.setState({ value: new_state })
  },
  render: function() {
    me = this

    // console.log(this.state.value)
    lines = this.state.value.map( function(e, i) {
      return (
        <div key={i}>
          <input value={e} />
          <button onClick={me.remove_item} >X</button>
        </div>
      )
    })

    return (
      <div>
        {lines}
        <button onClick={this.add_more}>Add More</button>
      </div>
    )
  }
})

1 个答案:

答案 0 :(得分:2)

这里有一些事情发生。

首先,在数组中呈现时不应使用数组索引作为键:

lines = this.state.value.map( function(e, i) {
  return (
    <div key={i}>
      <input value={e} />
      <button onClick={me.remove_item} >X</button>
    </div>
  )
})

第一次,["A", "B", "C"]呈现:

    <div key={0}>
      ...
    </div>
    <div key={1}>
      ...
    </div>
    <div key={2}>
      ...
    </div>

然后,第二次,当您移除"B"并离开["A", "C"]后,它会呈现以下内容:

    <div key={0}>
      ...
    </div>
    <div key={1}>
      ...
    </div>

因此,当您在索引1处删除项目时,索引2上的项目将移至索引1。您将需要使用一些在数组中的位置更改时不会更改的唯一值。

其次,您应该使用空字符串而不是null进行初始化,然后您将看到您无法在输入中键入任何内容。那是因为value确保输入的值始终是你通过它的任何值;您必须附加onChange处理程序才能允许编辑值。

更改为defaultValue允许您输入框,但是当您键入时,this.state.value中的字符串不会更新 - 您仍然需要onChange处理程序

最后,您的按钮的onClickthis.remove_item,但您的remove_item方法似乎将事件和索引作为参数。但是,React不会将当前索引传递给remove_item;你需要创建一个传递正确参数的新函数:

onClick={me.remove_item.bind(null, i)}

那就是说,你真的不应该在Function#bind内调用render因为你每次运行都会创建新的函数。