在反应tic tac toe tutorial中,为什么他们必须使用Array.slice()?
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});
}
他们无论如何改变 state.squares 吧?试着了解最新情况。
答案 0 :(得分:2)
这是创建新数组并将所有元素复制到其中的常用方法。这是将 new 数组传递给setState
而不是改变旧数组 - 这不会导致组件重新渲染。
新数组将导致重新渲染。如果你像这样改变了数组:
this.props.squares[i] = 'X';
反应不会被通知该状态发生了变化。
答案 1 :(得分:2)
你不应该直接改变状态,所以当你写
时handleClick(i) {
const squares = this.state.squares.slice(); // you are creating a new copy of the squared array,
squares[i] = 'X';
this.setState({squares: squares});
}
您对克隆状态所做的任何更改都不会反映在原始状态上。
当您希望使用生命周期方法并比较prevState和currentState时,突变特别麻烦,例如,如果您设置状态
handleClick(i) {
const squares = this.state.squares;
squares[i] = 'X';
this.setState({squares: squares});
}
在这种情况下说,在componentDidUpdate
函数中,您希望根据正方形数组中的更改执行操作,
componentDidUpdate(prevProps, prevState) {
if(nextState.squares !== this.state.squares) {
// do something here
}
}
在上述情况下,比较将失败,因为prevState
和this.state
将返回与改变原始状态相同的结果。
还需要调用setState
才能重新渲染