在 javascript 中,对象分配通过引用工作,因此即使您在 setState 之外改变变量,只要您不克隆对象,它仍然会引用相同的状态引用。但是,如果您克隆它,则会创建一个新实例,而不会影响原始实例
addRow = () => {
const persons = [...this.state.persons] // Clone it one level deep using spread
persons.push({
name: '',
age: ''
})
this.setState({
persons
})
}
以上可以使用 simplespread syntax
和functional setState
like来完成
addRow = () => {
this.setState(prevState => ({
persons: [...prevState.persons, { name: '', age: ''}]
}))
}
尽管在您的示例中,这两个操作之间似乎没有区别,但您提供的初始实现存在重大缺陷。为了查看克隆和推送与仅分配引用和推送之间的区别,您可以看到codesandbox demo
.
基本上,当您创建一个新组件时,如果您将状态人作为props传递给该组件,并在其原始引用处进行变异,则在componentWillReceiveProps
方法中,您会看到 thecurrentProps
和 thenextProps
都是相同的,因此如果您对子项进行任何检查如果人员props发生变化,则采取行动的组件将失败。因此,不要在其自己的参考中改变值是非常重要的
没有 push 和 spread 语法,您仍然可以通过使用 concat 创建原始数组的新副本来避免变异问题
addRow = () => {
this.setState(prevState => ({
persons: prevState.persons.concat([{ name: '', age: ''}])
}))
}