Javascript 更改处于反应状态的二维阵列
我有这样一个初始状态:Javascript 更改处于反应状态的二维阵列,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我有这样一个初始状态: constructor(props) { super(props); this.state = this.getInitialState(); this.setSqValue = this.setSqValue.bind(this); } getInitialState() { return { allSq: new Array(3).fill(new Array(3).fill(null)) }; } 然后
constructor(props) {
super(props);
this.state = this.getInitialState();
this.setSqValue = this.setSqValue.bind(this);
}
getInitialState() {
return {
allSq: new Array(3).fill(new Array(3).fill(null))
};
}
然后,在像setSqValue
(通过单击按钮调用)这样的方法中,当我为一个单元格指定一个新值时,奇怪的是,在第一维中任何位置和第二维中相同位置的所有其他单元格都将取该值
第二个问题是,当我没有调用任何setState
时,状态发生了更改
setSqValue(i, j) {
console.log(i, j);
let {allSq} = this.state;
let value = 'foo';
console.log('before', allSq);
allSq[i][j] = value;
console.log('after', allSq);
// this.setState({allSq});
}
控制台中的输出如下所示:
您可以看到前后值相同(为什么?!)
React developer工具中的状态:
在JavaScript中,
数组是一种特殊的对象
,如果将一个对象传递给fill()
,它每次都使用相同的对象。您应该改用map()
,这将创建数组的副本
allSq: Array(3).fill().map(() => Array(3).fill(null))
要防止状态被更改,您可以使用Object.freeze()
方法:
allSq: Object.freeze(Array(3).fill().map(() => Object.freeze(Array(3).fill(null))))
这样,行allSq[i][j]=值
将抛出错误(在严格模式之外)或静默失败(在严格模式之外)。在JavaScript中,数组是一种特殊的对象,如果将对象传递给fill()
,它每次都使用相同的对象。您应该改用map()
,这将创建数组的副本
allSq: Array(3).fill().map(() => Array(3).fill(null))
要防止状态被更改,您可以使用Object.freeze()
方法:
allSq: Object.freeze(Array(3).fill().map(() => Object.freeze(Array(3).fill(null))))
这样,行allSq[i][j]=值代码>将抛出错误(在严格模式之外)或静默失败(在严格模式之外)。在chrome开发工具中,对象在打开之前不会被评估。将鼠标悬停在右边的小图标上,您将看到下面的对象刚刚被计算过。
。尝试将调试器
放在那里,我有一种感觉,您会看到前面的allSq
中没有foo
。看起来好像一切正常,你只是在看错误的东西
另外,正如另一位用户所说,.fill
使用引用而不是值,因此请使用.map
来代替。在chrome开发工具中,只有打开对象才会对其进行评估。将鼠标悬停在右边的小图标上,您将看到下面的对象刚刚被计算过。
。尝试将调试器
放在那里,我有一种感觉,您会看到前面的allSq
中没有foo
。看起来好像一切正常,你只是在看错误的东西
另外,正如另一位用户所说,.fill
使用引用而不是值,因此请使用.map
。谢谢。但第二个问题仍然存在。分配给allSq正在更改状态,而不使用setState。我可以在react开发者工具中看到它。但是,应用程序的行为就像什么都没有发生一样。@AmirhosseinDZ请查看我的编辑。应用程序的行为就像什么也没发生一样,因为React不监视状态对象的更改;仅当状态由setState
方法更改时,它才会更新组件。谢谢。但第二个问题仍然存在。分配给allSq正在更改状态,而不使用setState。我可以在react开发者工具中看到它。但是,应用程序的行为就像什么都没有发生一样。@AmirhosseinDZ请查看我的编辑。应用程序的行为就像什么也没发生一样,因为React不监视状态对象的更改;只有通过setState
方法更改状态时,它才会更新组件。