【问题标题】:Update state of array nested inside object (ReactJS)更新嵌套在对象内的数组的状态(ReactJS)
【发布时间】:2017-12-15 00:02:24
【问题描述】:

我有一个具有多个键的状态对象(“汽车”),其中一个是数组(“特征”)。我正在尝试用它做几件事。

  1. 每次单击“添加功能”按钮时,我都想将另一个字符串(另一个功能)推送到“功能”数组中。
  2. 当我输入相应的输入时,我希望能够更新“功能”数组中每个字符串/功能的状态。

我在网上对此进行了相当多的研究,但没有发现任何东西(可能是因为这不可能)。无论哪种方式,这是我的代码:

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>
    )
  }
}

【问题讨论】:

  • 你能举个例子“当我输入相应的输入时,我希望能够更新“特征”数组中每个字符串/特征的状态?”

标签: javascript arrays reactjs state


【解决方案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 变量的定义。事实证明,这是更新嵌套在状态对象中的单个键的唯一方法。

【讨论】:

    【解决方案2】:

    广告 1

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

    只需创建副本并推送汽车功能即可获得新价值。

    广告。 2 创建名为例如的组件特征。他将拥有自己的状态,您可以在其中修改字符串并通过道具将数据提取到“汽车”。

    【讨论】:

      【解决方案3】:

      有一些事情可能会导致您出现问题...如果您的组件具有状态,您应该使用构造函数,并在其中绑定您的“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)
        }
      

      这篇文章非常适合思考“这个”: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 解构有一个有趣的事情,如果一个键和它的值相同,你只需要引用它一次,它就会计算出来。这只是让您的代码保持干燥的一种很酷的方式。

      【讨论】:

      • 好的,在这里感谢您的帮助,对于延迟回复感到抱歉。我最终做了一些与您的建议非常相似的事情,我在下面的答案中概述了这些建议,因为我需要更多空间。
      猜你喜欢
      • 1970-01-01
      • 2018-10-10
      • 2020-05-22
      • 2022-07-07
      • 2020-04-27
      • 2018-07-04
      • 2020-12-08
      • 2021-12-23
      • 2019-08-28
      相关资源
      最近更新 更多