更新嵌套在对象内的数组的状态(ReactJS)

时间:2017-12-15 00:02:24

标签: javascript arrays reactjs state

我有一个状态(“car”)的对象有多个键,其中一个是一个数组(“features”)。我正试图用它做几件事。

  1. 每次单击“添加功能”按钮时,我想将另一个字符串(另一个功能)推送到“features”数组。
  2. 当我输入相应的输入时,我希望能够更新“features”数组中每个字符串/功能的状态。
  3. 我在网上研究过这个并没有找到任何东西(也许是因为这是不可能的)。不管怎样,这是我的代码:

    class Car extends React.Component {
    
      state = {
        car: {make: 'Toyota', model: 'Camry', features: []},
      }
    
    
      handleChange = (e, index) => {
        const value = e.target.value
        let features = this.state.car.features.slice() // create mutable copy of array
        features = features[index].concat(value)
        this.setState({...this.state.car, features: features})
      }
    
      handleAddFeature = () => {
        let features = this.state.car.features.slice()
        features.push('')
        this.setState({...this.state.car, features: features})
      }
    
      render() {
        return (
          {
            this.state.car.features.map((f, index) => { return <input key={index} onChange={e => this.handleChange(e, index)}>{feature}</input>
          }
          <button onClick={this.handleAddFeature}>Add Feature</button>
        )
      }
    }
    

3 个答案:

答案 0 :(得分:1)

好的,我的工作方式与@ Snkendall的答案非常相似。我的handleChange功能如下:

handleChange = (e, index,) => {
  let array = this.state.car.features.slice() // create mutable copy of the array
  array[index] = e.target.value // set the value of the feature at the index in question to e.target.value
  const newObj = { ...this.state.car, features: array } // create a new object by spreading in the this.state.car and overriding features with our new array 
  this.setState({ car: newObj }) // set this.state.car to our new object
}

此解决方案与@ Snkendall之间的区别在于定义newObj变量。结果证明这是更新嵌套在状态对象中的单个键的唯一方法。

答案 1 :(得分:0)

Ad.1

  handleAddFeature = () => {
    const car = this.state.car
    car.features.push('Your feature')
    this.setState({ car })
  }

只需创建副本并推送到汽车功能新值。

广告。 2 创建名为eg的组件特征。他将拥有你修改字符串的状态,通过道具你可以将数据提取到你的“汽车”。

答案 2 :(得分:0)

有一些事情可能会导致你的问题...如果你的组件有一个状态,你应该使用一个构造函数,并在其中绑定你的'this'引用,以防止'this'引用全局。你只需这样包裹你的状态:

class Car extends React.Component {
   constructor() {
     super()
     this.state = {
      car: {make: 'Toyota', model: 'Camry', features: []},
    }
    this.handleChange = this.handleChange.bind(this)
    this.handleAddFeature = this.handleAddFeature.bind(this)
  }

这是一篇非常棒的关于'this'的文章:http://2ality.com/2017/12/alternate-this.html

另一个可能导致问题的区域是features = features[index].concat(value) ...因为您在每次更改(键击)时一遍又一遍地将输入标记的值连接到当前字符串状态。您可以像这样重置数组中该索引处元素的值:

handleChange = (e, index) => {
  const value = e.target.value
  let features = this.state.car.features.slice()
  features[index] = value
  this.setState({...this.state.car, features})
}

这样,每次击键只会重置状态值以反映输入中创建的更改。实际上你根本不需要使用handleAddFeature,因为状态已经用handleChange更新了。

我正在将features:features更改为features因为ES6解构有这个有趣的事情,如果一个键和它的值是相同的,你只需要引用它一次,它就会发现它。这只是保持代码干净的一种很酷的方式。