在es6中添加行而不推送

时间:2018-10-16 05:38:14

标签: javascript reactjs ecmascript-6

我不确定自己在做正确的事,我在setState之外对变量进行了突变,对吗?还是有更优雅的方法呢?

state = {
    persons: [{
      name: 'jay',
      age: 10
    }]
  }
  addRow = () => {
    const temp = this.state
    temp.persons.push({
      name: '',
      age: ''
    })
    this.setState({
      ...temp
    })
  }

应用程序演示https://codesandbox.io/s/ppqw4wjqzq

2 个答案:

答案 0 :(得分:2)

在javascript中,对象分配是通过Referece进行的,因此,即使您在setState之外对变量进行了更改,只要您不克隆对象,它仍将引用相同的state引用。但是,如果您克隆它,则将创建一个新实例,而原始实例将不受影响

addRow = () => {
    const persons = [...this.state.persons] // Clone it one level deep using spread
    persons.push({
      name: '',
      age: ''
    })
    this.setState({
      persons
    })
  }

只需使用spread syntaxfunctional setState即可完成上述操作

addRow = () => {
    this.setState(prevState => ({
      persons: [...prevState.persons, { name: '', age: ''}]
    }))
  }

尽管在您的示例中这两个动作之间似乎没有什么区别,但是您提供的初始实现中存在重大缺陷。为了了解克隆和推送之间的区别以及仅分配引用和推送之间的区别,您可以看到codesandbox demo

基本上,当您创建一个新组件时,如果您将状态人员作为道具传递给该组件,并且在其原始引用处进行了变异,则在componentWillReceiveProps方法中,您会看到currentProps和{ {1}}都是相同的,因此,如果您对子组件进行了任何检查,如果这些人的道具发生了更改,那么该组件将失败。因此,非常重要的一点是,不要根据自己的引用来更改值

没有push和spread语法,您仍然可以通过使用concat来创建原始数组的新副本来避免突变问题

nextProps

答案 1 :(得分:1)

我认为,更优雅的方法是使用功能setState

const newPerson = { name: '', age: -1 };
this.setState(prevState => ({ persons: [...prevState.persons, newPerson] })