Javascript 为react状态添加不带推入es6的行

Javascript 为react状态添加不带推入es6的行,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我不确定我做的是对的,我在setState之外变异变量,没问题吧?还是有更优雅的方式 state = { persons: [{ name: 'jay', age: 10 }] } addRow = () => { const temp = this.state temp.persons.push({ name: '', age: '' }) this.setState({

我不确定我做的是对的,我在setState之外变异变量,没问题吧?还是有更优雅的方式

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

App demo

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

addRow = () => {
    const persons = [...this.state.persons] // Clone it one level deep using spread
    persons.push({
      name: '',
      age: ''
    })
    this.setState({
      persons
    })
  }
可以简单地使用
扩展语法
功能设置状态
等来完成上述操作

addRow = () => {
    this.setState(prevState => ({
      persons: [...prevState.persons, { name: '', age: ''}]
    }))
  }
虽然在您的示例中,这两个操作之间似乎没有区别,但您提供的初始实现中存在重大缺陷。为了查看克隆和推送与仅分配引用和推送之间的区别,您可以查看

基本上,当您创建一个新组件时,如果您将state persons作为props传递给该组件,并且在其原始引用处进行变异,则在
componentWillReceiveProps
方法中,您可以看到
currentProps
nextrops
都是相同的,因此,如果您在子组件中进行了任何检查,以便在persons prop发生更改时采取操作,则该操作将失败。因此,极为重要的是,不要在其自身的引用处改变该值

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

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

在我看来,更优雅的方法是使用functional
setState

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

克隆或分配都无所谓,对吗?我想避开,推?怎样才能做到呢?使用map?@Melissa94,如果你克隆或分配,它不会起作用。我正在添加一个示例spread执行此任务,为什么需要在上一个示例中使用concat?@Melissa94,concat与push类似,只是它返回一个新数组,而不是对原始数组进行变异。在spread示例中,您使用了prevState,如果不使用回调会怎么样?是这样吗
this.setState({persons:[…this.state.person,{name:'',age:'}]})
它不是currentState,而是prevState,不是吗?它是最近的一个