2017-04-20 40 views
3

lifeParser是一種調用來處理和更新boardData的方法。問題是boardData在循環處理過程中得到更新。狀態在調用setState之前得到更新

lifeParser(){ 
    var parseArray = this.state.boardData.slice(0); 

    for(var i=0;i<30;i++){ 
     for(var j=0;j<30;j++){ 
      parseArray[i][j] = 5; // boardData gets updated here before setState is even called 
     } 
    } 
    this.setState({boardData : parseArray}); 
} 
+3

因爲 「第二級」,即'[j]的'是相同的數據爲'this.state.boardData [N] [j]的' - 也就是說,你已經對數組的「第一層」進行了切分,但是每個'parseArray [n]'中的數組引用與'this.state.boardData [n]'中相同的數據' –

回答

2

這是因爲你的boardData是多維的,你不僅可以slice方法克隆。像這樣與map一起使用。

​​

或與箭頭語法

var parseArray = this.state.boardData.map(a => a.slice()); 
2

因爲它是一個嵌套數組。你只是複製第一層(淺層克隆)。內部數組仍然是相同的引用。考慮如下例子:

var nestedArray = [ 
[1, 2, 3], 
[6, 6, 6, 6, 7, 8], 
[0, 3, 5, 6, 5] 
]; 

// This only does a shallow clone 
var copy = nestedArray.slice(0); 

// When you do this 
copy[0][0] = 100; 

// `nestedArray` will also be mutated, 
// you get 100 here 
console.log(nestedArray[0][0]); 

在你的情況,你可以做一個深克隆或簡單地使用類似map()獲得一個全新的數組:

lifeParser(){ 
    var parseArray = this.state.boardData.slice(0); 

    for (var i = 0; i < 30; i++) { 
     parseArray[i] = parseArray[i].map(() => 5); 
    } 
    this.setState({boardData : parseArray}); 
} 

在這個例子做了深刻的克隆更貴,因爲你需要更多的循環。這裏使用map()的好處是您可以同時計算和克隆數據。

也可以在本實施例中使用兩個map() S:

lifeParser(){ 
    var parseArray = this.state.boardData.map(innerArray => innerArray.map(() => 5)); 
    this.setState({boardData : parseArray}); 
} 

// Or this might be more readable: 
var parseArray = this.state.boardData.map(innerArray => { 
    return innerArray.map(() => 5); 
}); 
相關問題