React - 生命游戏 - 根据用户点击的元素更新 2D 数组中特定元素的状态
React - Game of Life - Update state of specific elements in 2D array depending on which elements are clicked by user
我仍在学习 React 并致力于编写 John Conway 的 Game of Life。我已经使用状态中的二维数组为游戏创建了一个游戏板。我将这个二维数组存储在我的 App.js
中。我还有两个功能组件,Gameboard.js
和 Square.js
接收道具并创建游戏板。
Gameboard.js
创建一个 table 并将道具传递给 Square.js
让它知道哪些方块应该突出显示,哪些不应该突出显示。换句话说,它让每个单独的方块都知道用户是否点击了它,以及它是否是 Game of Life 意义上的 "alive"。
在用户单击 Square.js
中的特定方块后,我有一个触发 onClick 的回调函数。回调函数 aliveCallback
将被单击的特定方块的 X 和 Y 坐标传递回 App.js
。 App.js
触发一个名为 alive
的函数。
当调用 alive
时,我需要更新二维数组的状态,以便特定的正方形(它是 X 和 Y 坐标,例如 [0, 0] 或 [0, 1] 等) ..) 设置为存储在状态中的布尔值。然后,这个布尔值可以作为 isAlive
传递给 Gameboard.js
。游戏板然后将 isAlive
值传递给 Square.js
并且 Square.js
具有条件渲染,告知要突出显示的单个方块为浅蓝色。
这已经满嘴了,可能最容易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 。
阅读和查看 React 文档后,似乎解决此问题的一个好方法是使用 immutability-helper 和它的 update
函数。这是我采用的方法,但我似乎无法正确更新使用 X 和 Y 坐标单击的特定方块的状态。
与其在此处发布代码,不如在 CodeSandbox 上查看代码更容易、更整洁。我如何编写我的 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 updateData = update(data, {
xSquare: {$set: this.setState({ alive: !this.state.alive })}
});
}
这里的逻辑是尝试将 xSquare 和 ySquare 传递给 update
,然后尝试将该特定正方形设置为 alive。
我认为问题在于您在 App 上有一个状态变量 alive
,它与每个细胞的生命状态混淆。
我修改了一些东西,我的解决方案没有使用 update from 'immutability-helper'
因为我不熟悉它,但我认为我的解决方案中的逻辑非常简单。
这里是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
,否则保留它不变。
作为附加说明,我建议将此方法重命名为 makeCellAlive
之类的名称,以便更清楚地表明它是一种执行某些操作的方法。
编辑:
如果您希望根据细胞的当前状态单击使细胞存活或死亡,您可以更改行:
row.map((cell, x) => x === xSquare ? 1 : cell)
至
row.map((cell, x) => x === xSquare ? (cell + 1) % 2 : cell)
顺便说一句,看起来是个很酷的应用。
我仍在学习 React 并致力于编写 John Conway 的 Game of Life。我已经使用状态中的二维数组为游戏创建了一个游戏板。我将这个二维数组存储在我的 App.js
中。我还有两个功能组件,Gameboard.js
和 Square.js
接收道具并创建游戏板。
Gameboard.js
创建一个 table 并将道具传递给 Square.js
让它知道哪些方块应该突出显示,哪些不应该突出显示。换句话说,它让每个单独的方块都知道用户是否点击了它,以及它是否是 Game of Life 意义上的 "alive"。
在用户单击 Square.js
中的特定方块后,我有一个触发 onClick 的回调函数。回调函数 aliveCallback
将被单击的特定方块的 X 和 Y 坐标传递回 App.js
。 App.js
触发一个名为 alive
的函数。
当调用 alive
时,我需要更新二维数组的状态,以便特定的正方形(它是 X 和 Y 坐标,例如 [0, 0] 或 [0, 1] 等) ..) 设置为存储在状态中的布尔值。然后,这个布尔值可以作为 isAlive
传递给 Gameboard.js
。游戏板然后将 isAlive
值传递给 Square.js
并且 Square.js
具有条件渲染,告知要突出显示的单个方块为浅蓝色。
这已经满嘴了,可能最容易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
阅读和查看 React 文档后,似乎解决此问题的一个好方法是使用 immutability-helper 和它的 update
函数。这是我采用的方法,但我似乎无法正确更新使用 X 和 Y 坐标单击的特定方块的状态。
与其在此处发布代码,不如在 CodeSandbox 上查看代码更容易、更整洁。我如何编写我的 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 updateData = update(data, {
xSquare: {$set: this.setState({ alive: !this.state.alive })}
});
}
这里的逻辑是尝试将 xSquare 和 ySquare 传递给 update
,然后尝试将该特定正方形设置为 alive。
我认为问题在于您在 App 上有一个状态变量 alive
,它与每个细胞的生命状态混淆。
我修改了一些东西,我的解决方案没有使用 update from 'immutability-helper'
因为我不熟悉它,但我认为我的解决方案中的逻辑非常简单。
这里是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
,否则保留它不变。
作为附加说明,我建议将此方法重命名为 makeCellAlive
之类的名称,以便更清楚地表明它是一种执行某些操作的方法。
编辑:
如果您希望根据细胞的当前状态单击使细胞存活或死亡,您可以更改行:
row.map((cell, x) => x === xSquare ? 1 : cell)
至
row.map((cell, x) => x === xSquare ? (cell + 1) % 2 : cell)
顺便说一句,看起来是个很酷的应用。