本文介绍了React-生命游戏-根据用户单击的元素来更新2D数组中特定元素的状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍在学习React并致力于编写John Conway的《生活游戏》.我已经使用状态为2D的数组为游戏创建了一个游戏板.我将此二维数组存储在App.js中的状态中.我还有两个功能组件,Gameboard.jsSquare.js接收道具并创建游戏板.

I'm still learning React and working on coding John Conway's Game of Life. I have created a game board for the game using a 2D array in state. I have this 2D array stored in state in my App.js. I also have two functional components, Gameboard.js and Square.js receiving props and creating the game board.

Gameboard.js创建一个表格并将道具传递给Square.js,让其知道哪些正方形应突出显示,哪些不应当突出显示.换句话说,它让每个单独的方块都知道用户是否单击了它,以及它是否在生命游戏"意义上是活跃的".

Gameboard.js creates a table and passed props to Square.js letting it know which squares should be highlighted and which shouldn't. In other words it let's each individual square know if the user has clicked it and if it's "alive" in the Game of Life sense.

用户单击Square.js中的特定正方形后,我有一个触发了onClick的回调函数.回调函数aliveCallback将被单击的特定正方形的X和Y坐标传递回App.js. App.js触发一个称为alive的函数.

After a user clicks a specific square in Square.js I have a callback function triggered onClick. The callback function, aliveCallback, passes the X and Y coordinates of the specific square that was clicked back to App.js. App.js triggers a function called alive.

当调用alive时,我需要更新2D数组的状态,以使特定的正方形(它是X和Y坐标,例如[0,0]或[0,1]等).设置为存储在状态中的布尔值.然后,该布尔值可以作为isAlive传递给Gameboard.js.然后,游戏板将该isAlive值传递给Square.js,并且Square.js具有条件渲染,该渲染指示单个正方形被突出显示为浅蓝色.

When alive is called I need to update the state of the 2D array so that the specific square (it's X and Y coordinates, for example [0, 0] or [0, 1] etc...) is set to the boolean stored in state. Then, this boolean can be passed to Gameboard.js as isAlive. The game board then passes that isAlive value to Square.js and Square.js has conditional rendering that tells that individual square to be highlighted light blue.

这真是令人难以置信,很容易签出Codesandbox并查看项目的结构.这也有助于提及我正在遵循SO海报在.

This has been a mouth full and it would probably be easiest to check out the Codesandbox and see the structure of the project. It also helps to mention that I am following advice a SO poster gave me in this post.

阅读并查看React文档后,看来解决此问题的好方法是使用不可变性帮助程序,它是update函数.这就是我采用的方法,但是我似乎无法使用其X和Y坐标正确地更新所单击的特定正方形的状态.

After doing some reading and looking at the React docs it appears a good approach to this issue is to use immutability-helper and it's update function. That's the approach I have taken but I can't seem to properly update the state of the specific square clicked using it's X and Y coordinates.

与其在此处发布代码,不如在CodeSandbox上签出代码可能更容易,更整洁.如何编写我的alive函数,以便它正确更新所单击的正方形的状态?

Instead of posting code here it would probably just be easier and neater to check out the code on CodeSandbox. How can I write my alive function so that it properly updates the state of whatever square is clicked on?

这是我尝试过的:

alive = (x, y) => {
    console.log(x, y);

    const data = this.state.board;
    const ySquare = y;
    const xSquare = x;
    console.log("X square is : " + xSquare);
    console.log("Y square is : " + ySquare);

    const updateData = update(data, {
      xSquare: {$set: this.setState({ alive: !this.state.alive })}
    });

  }

这里的逻辑是尝试将xSquare和ySquare传递给update,然后尝试为该特定正方形将live设置为true.

The logic here is to try to pass xSquare and ySquare to update and then try to set alive to true for that particular square.

推荐答案

我认为问题是您在App上有一个状态变量alive,该变量对于每个单元格的生命状态感到困惑.

I think the problem is that you have a state variable alive on the App which is being confused for the life status of each cell.

我做了一些重做,我的解决方案不使用update from 'immutability-helper',因为我不熟悉它,但是我认为解决方案中的逻辑非常简单.

I've reworked things a bit, and my solution does not use update from 'immutability-helper' since I'm not familiar with it, but the logic in my solution is pretty straightforward I think.

这里是App.alive:

alive = (x, y) => {
  console.log(x, y);

  const data = this.state.board;
  const ySquare = y;
  const xSquare = x;
  console.log("X square is : " + xSquare);
  console.log("Y square is : " + ySquare);

  const newData = data.map((row, y) => {
    return y === ySquare ? (
      row.map((cell, x) => x === xSquare ? 1 : cell)
    ) : (
      row
    )
  })

  this.setState({ board: newData });
}

基本上,newData来自检查板上的每个单元格,并且如果当前单元格的坐标与xSquare, ySquare相匹配,则它将单元格的值设置为1,否则它将保持不变.

Basically newData comes from going over each cell in the board and if the current cell's coordinates match xSquare, ySquare it sets the value of the cell to 1, otherwise it leaves it unchanged.

作为补充说明,我建议将此方法重命名为makeCellAlive之类的名称,以便更清楚地表明它是一种可以执行某些操作的方法.

As an additional note, I'd recommend renaming this method to something like makeCellAlive just to be more clear that it is a method that does something.

修改:

如果您想单击鼠标以根据其当前状态使该单元处于活动状态或死亡状态,则可以更改该行:

If you wanted to have click either make the cell alive or dead depending on it's current state, you could change the line:

row.map((cell, x) => x === xSquare ? 1 : cell)

row.map((cell, x) => x === xSquare ? (cell + 1) % 2 : cell)

看起来像一个很棒的应用.

Looks like a cool app btw.

这篇关于React-生命游戏-根据用户单击的元素来更新2D数组中特定元素的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 02:23