正确处理从状态中保持的数组映射的输入元素的值更改的方法

时间:2018-02-22 12:46:38

标签: reactjs

我是React的新手,我正在努力确保从映射数组创建的表单元素仍由React控制

我有一个通过props

传递给React组件的对象数组
vehicles: [
    {make: 'make1', model: 'model1'},
    {make: 'make2', model: 'model2'}
]

我然后将这些存储在状态中(有问题的React组件的目的是在其源头修改车辆阵列)

componentWillReceiveProps() {
    this.setState({
        vehicles: this.props.vehicles
    })
}

在此之后我通过数组进行映射以创建要在render()中返回的jsx

const vehicles = this.state.vehicles.map((vehicle, index) => {
    return (
        <div>
            <FormGroup row>
                <Col sm={1}></Col>
                <Label for={`make-${index}`} sm={3}>Make</Label>
                <Col sm={7}>
                    <Input type="text" name={`make-${index}`} id={`make-${index}`} data-context="vehicle" onChange={this.handleInputChange} value={vehicle.make} readOnly={!this.state.formEnabled} />
                </Col>
                <Col sm={1}></Col>
            </FormGroup>
            <FormGroup row>
                <Col sm={1}></Col>
                <Label for={`model-${index}`} sm={3}>Model</Label>
                <Col sm={7}>
                    <Input type="text" name={`model-${index}`} id={`model-${index}`} data-context="vehicle" onChange={this.handleInputChange} value={vehicle.model} readOnly={!this.state.formEnabled} />
                </Col>
                <Col sm={1}></Col>
            </FormGroup>
        </div>
    );
})

但是,以这种方式设置值意味着我无法使用handleInputChange()功能更改其状态(甚至可以在浏览器的输入字段中输入文本)。

有没有办法保持动态创建的表单元素由React控制?或者我的方法是否存在根本缺陷?

1 个答案:

答案 0 :(得分:1)

您可以将索引作为数据属性传递给输入,然后更新handleInputChange函数中的数组并使用新数组更新状态。像这样:

handleInputChange(event) {
  const thisVehicleIndex = event.target.dataset.item
  let vehicles = this.state.vehicles
  let thisVehicle = vehicles[thisVehicleIndex]
  // Handle your update thisVehicle, then...
  vehicles[thisVehicleIndex] = thisVehicle
  this.setState({
    vehicles: vehicles
  })
}

您的输入看起来像这样(请注意新的数据项属性):

<Input type="text" name={`make-${index}`} id={`make-${index}`} data-context="vehicle" data-item={index} onChange={this.handleInputChange} value={vehicle.make} readOnly={!this.state.formEnabled} />