【问题标题】:state gets updated before setState is called在调用 setState 之前状态会更新
【发布时间】:2017-09-16 11:29:24
【问题描述】:

lifeParser 是一个用于处理和更新 boardData 的方法。问题是 boardData 在循环仍在处理时得到更新。

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});
}

【问题讨论】:

  • 因为“第二层”即[j]this.state.boardData[n][j] 是相同的数据 - 即您已经切片了数组的“第一层”,但每个parseArray[n] 中的数组是引用与this.state.boardData[n]中相同的数据

标签: javascript arrays reactjs


【解决方案1】:

这是因为你的boardData 是多维的,你不能只用slice 方法克隆它。像这样与map 一起使用。

var parseArray = this.state.boardData.map(function(arr) {
    return arr.slice();
});

或使用箭头语法

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});
    }
    

    在此示例中进行深度克隆的成本更高,因为您需要多 1 个循环。在这里使用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);
    });
    

    【讨论】:

      猜你喜欢
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      • 2020-01-30
      • 1970-01-01
      • 2018-12-08
      相关资源
      最近更新 更多