React - 使用 componentDidUpdate 根据从另一个函数传递的数据更新状态
React - Using componentDidUpdate to update state based on data passed from another function
我正在学习 React 并正在开发 John Conway 的 Game of Life 应用程序。我在 state/the 构造函数中定义了一个二维数组,它创建了一个正方形游戏板。我有一个名为 isSquareAlive
的函数,它处理网格中的特定方块在生命游戏意义上是否为 "alive" 并更新方块并将它们设置为在用户单击它们时处于活动状态。我还有另一个名为 selectBoardSize
的函数,它允许用户单击一个按钮并调整面板的大小。
当应用程序安装时,我生成了一个随机板,其中填充了一些设置为 "alive" 的方块,有些则没有。我在里面处理这个 componentDidMount
:
componentDidMount = () => {
const data = this.state.board;
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
board: rounded
});
}
这很好用。如果用户尝试通过 selectBoardSize
调整板的大小,我想更改板的大小,然后再次用随机 "alive" 单元格填充它。这里是 selectBoardSize
:
// Allows user to click button and change size of game board
selectBoardSize = (width, height) => {
this.setState({
boardHeight: height,
boardWidth: width,
board: Array(this.state.boardHeight).fill(0).map(_ =>
Array(this.state.boardWidth).fill(0))
});
{/*this.onChangeBoardSize(width, height);*/}
}
当用户更改电路板尺寸时,我尝试使用 componentDidUpdate
获取新的电路板尺寸并用该电路板尺寸的随机 "alive" 单元格填充它,就像我最初做的那样componentDidMount
。这是我遇到困难的地方。
这是我的 componentDidUpdate
:
// Attempts to fill board with random alive squares when user resizes the size of the board via onClick/selectBoardSize()
componentDidUpdate = (prevProps, prevState) => {
console.log('PrevState is : ' + prevProps, prevState);
// Attempts to update board height and width and then populate board with random "alive" squares
if(this.state.boardWidth !== prevState.boardWidth) {
if(this.state.boardHeight !== prevState.boardHeight) {
// Console.log runs, if statements equate to true when user resizes board
console.log('Nested if statements in componentDidUpdate triggered');
const boardWidth = this.state.boardWidth;
const boardHeight = this.state.boardHeight;
const data = this.state.board;
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
boardWidth: boardWidth,
boardHeight: boardHeight,
board: rounded
})
}
}
}
当用户单击按钮调整它的大小时,该板成功地更改了尺寸,但它不会像它应该的那样生成随机的 "alive" 方块。它只是改变了板的高度和宽度,但板是空的。
如何使用 componentDidUpdate
在调整大小时用随机 "alive" 单元格填充游戏板(类似于最初安装时的操作,但在板改变尺寸时适当调整大小) . componentDidUpdate
是正确的方法吗?这是 setState 异步的问题吗?
很确定我想多了。
您可以在 codesandbox 上查看代码。
您不需要为此使用 componentDidUpdate
,稍后会详细介绍。
这不起作用,因为您(正确地,顺便说一下)将 componentDidMount
代码包装成两个条件,以检查 boardWidth
和 boardHeight
是否发生了变化。问题是,高度永远不会改变,所以它永远不会到达代码的那部分。
无论哪种方式,如果您仔细查看您的代码,就会发现您在不必要的情况下更新了太多次状态。如果您事先已经知道用户想要板子的尺寸,请一次完成。
据我了解,每次用户更改大小时您都希望执行以下操作:
- 根据所需的宽度和高度创建新板;
- 用随机的活方块填充它;
您只需要 onChangeBoardSize
功能,稍作改动。
请注意,您不需要从状态中检索板,因为它会因旧的宽度和高度而过时;
onChangeBoardSize = (width, height) => {
// Recreate board with new width and height values
const data = Array(height)
.fill(0)
.map(_ => Array(width).fill(0));
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
boardHeight: height,
boardWidth: width,
board: rounded
});
};
提示:注意过多的子顺序状态修改。总是喜欢一次完成所有事情而不是顺序触发 setState。特别是在 React 生命周期方法中
我正在学习 React 并正在开发 John Conway 的 Game of Life 应用程序。我在 state/the 构造函数中定义了一个二维数组,它创建了一个正方形游戏板。我有一个名为 isSquareAlive
的函数,它处理网格中的特定方块在生命游戏意义上是否为 "alive" 并更新方块并将它们设置为在用户单击它们时处于活动状态。我还有另一个名为 selectBoardSize
的函数,它允许用户单击一个按钮并调整面板的大小。
当应用程序安装时,我生成了一个随机板,其中填充了一些设置为 "alive" 的方块,有些则没有。我在里面处理这个 componentDidMount
:
componentDidMount = () => {
const data = this.state.board;
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
board: rounded
});
}
这很好用。如果用户尝试通过 selectBoardSize
调整板的大小,我想更改板的大小,然后再次用随机 "alive" 单元格填充它。这里是 selectBoardSize
:
// Allows user to click button and change size of game board
selectBoardSize = (width, height) => {
this.setState({
boardHeight: height,
boardWidth: width,
board: Array(this.state.boardHeight).fill(0).map(_ =>
Array(this.state.boardWidth).fill(0))
});
{/*this.onChangeBoardSize(width, height);*/}
}
当用户更改电路板尺寸时,我尝试使用 componentDidUpdate
获取新的电路板尺寸并用该电路板尺寸的随机 "alive" 单元格填充它,就像我最初做的那样componentDidMount
。这是我遇到困难的地方。
这是我的 componentDidUpdate
:
// Attempts to fill board with random alive squares when user resizes the size of the board via onClick/selectBoardSize()
componentDidUpdate = (prevProps, prevState) => {
console.log('PrevState is : ' + prevProps, prevState);
// Attempts to update board height and width and then populate board with random "alive" squares
if(this.state.boardWidth !== prevState.boardWidth) {
if(this.state.boardHeight !== prevState.boardHeight) {
// Console.log runs, if statements equate to true when user resizes board
console.log('Nested if statements in componentDidUpdate triggered');
const boardWidth = this.state.boardWidth;
const boardHeight = this.state.boardHeight;
const data = this.state.board;
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
boardWidth: boardWidth,
boardHeight: boardHeight,
board: rounded
})
}
}
}
当用户单击按钮调整它的大小时,该板成功地更改了尺寸,但它不会像它应该的那样生成随机的 "alive" 方块。它只是改变了板的高度和宽度,但板是空的。
如何使用 componentDidUpdate
在调整大小时用随机 "alive" 单元格填充游戏板(类似于最初安装时的操作,但在板改变尺寸时适当调整大小) . componentDidUpdate
是正确的方法吗?这是 setState 异步的问题吗?
很确定我想多了。
您可以在 codesandbox 上查看代码。
您不需要为此使用 componentDidUpdate
,稍后会详细介绍。
这不起作用,因为您(正确地,顺便说一下)将 componentDidMount
代码包装成两个条件,以检查 boardWidth
和 boardHeight
是否发生了变化。问题是,高度永远不会改变,所以它永远不会到达代码的那部分。
无论哪种方式,如果您仔细查看您的代码,就会发现您在不必要的情况下更新了太多次状态。如果您事先已经知道用户想要板子的尺寸,请一次完成。
据我了解,每次用户更改大小时您都希望执行以下操作:
- 根据所需的宽度和高度创建新板;
- 用随机的活方块填充它;
您只需要 onChangeBoardSize
功能,稍作改动。
请注意,您不需要从状态中检索板,因为它会因旧的宽度和高度而过时;
onChangeBoardSize = (width, height) => {
// Recreate board with new width and height values
const data = Array(height)
.fill(0)
.map(_ => Array(width).fill(0));
// Creates random decimal number between 0 and 1
const startingBoard = data.map(a => a.map(Math.random));
// Rounds decimal numbers to either 0 or 1 so the grid can display whether the cell is alive or dead
const rounded = startingBoard.map(a => a.map(Math.round));
this.setState({
boardHeight: height,
boardWidth: width,
board: rounded
});
};
提示:注意过多的子顺序状态修改。总是喜欢一次完成所有事情而不是顺序触发 setState。特别是在 React 生命周期方法中