从react.js中复制二维数组



我正在尝试构建一个小型React应用程序来建模Conway的生活游戏。我已经设置了一个二维阵列,以在10 x 10网格中跟踪每个单元格的状态。

我正在尝试将此数组存储在该州。在游戏的每个" tick"中,我想制作一个数组的副本,评估每个单元格,可能给它一个新的值,然后将副本分配回状态。我是根据官方的React教程来使用这种确切方法的官方React教程:

handleClick(i) {
    //Make a copy from state
    const squares = this.state.squares.slice();
    //Make some changes to it
    squares[i] = 'X';
    //Set state to the new value
    this.setState({squares: squares});
}

我最初的方法是如上示例中使用slice()。通过调试,我发现这不起作用。即使我使用各种方法来复制它不应该对其进行更改,即使状态正在改变。(我知道,如果我说var x = this.state.blahx = 5我已更改状态,因为blah是对它的参考)

这是我的代码:

doTick = () => {
    console.log("doin a tick");
    console.log(this.state.squares);
    //None of these approaches works
    //Three different copy strategies all fail
    //const newSquares = Object.assign({}, this.state.squares);
    //const newSquares = [...this.state.squares];
    //const newSquares = this.state.squares.slice();
    const newSquares = this.state.squares.slice();
    const origSquares = [...this.state.squares];
    //Iterating over the array
    for (var i = 0; i < 10; i++) {
      for (var j = 0; j < 10; j++) {
        newSquares[i][j] = evaluateCell(origSquares[i][j], this.countLiveNeighbors(i, j, origSquares));
        //evaluateCell(origSquares[i][j], this.countLiveNeighborsAndLog(i, j, origSquares));
      }
    }
    //this.setState({
      //squares: newSquares
    //});
  }

即使评论了setState()调用,只要将newSquares[i][j] = //...的分配就足以修改状态。

这是我在板组件的构造函数中设置初始数组的代码:

  constructor(props) {
    super(props);
    var array = new Array(10);
    for (var i = 0; i < 10; i++) {
      array[i] = new Array(10).fill(false);
    }
    this.state = {
      squares: array
    };
    console.log(this.state.squares);
  }

我在这里看一看,但是我在基于点击更新正方形时毫无困难(我的代码的那一部分正常工作)。各种如此的帖子和面对面的疑难解答者提出了三种不同的副本策略,这些策略都会产生相同的问题。我也在这里看一看。

我对JS的反应非常新手,而且在JS上不是很熟练,显然我对状态没有很好的处理。这是我的问题:

  1. 如何以状态的状态/数据的副本/一部分来制作副本不是对状态的方式?我希望能够在不改变状态的情况下更改此新数据(直到我准备就绪)。
  2. 为什么上面使用的方法无法正常工作?slice()的文档向我保证,我要获得副本而不是参考。

预先感谢!我很困惑。

传播运算符仅对值的 shallow 副本。这意味着,如果您的嵌套值中有任何嵌套值,则将被引用而不是复制。例如:

const a = { field: { innerField: 'test' } };
const b = { ...a } // b ===  { field: { innerField: 'test' } } SAME field as a

要复制一个嵌套数组,您应该使用深层复制方法,例如Lodash的Clonedeep或Ramda的克隆

例如,与lodash的克隆eep:

const newSquares = _.cloneDeep(this.state.squares);

最新更新