Я изучаю React и работаю над приложением Джона Конвея Game of Life.У меня есть 2D-массив, определенный в состоянии / конструкторе, который создает игровую доску из квадратов.У меня есть функция с именем isSquareAlive
, которая обрабатывает, является ли конкретный квадрат в сетке «живым» в смысле Игры Жизни, и обновляет квадраты и устанавливает их как живые, если пользователь нажимает на них.У меня также есть другая функция под названием selectBoardSize
, которая позволяет пользователю нажимать кнопку и настраивать размер доски.
Когда приложение монтируется, я генерирую случайную доску, заполненную некоторыми квадратами, установленными на "живые", а некоторые нет.Я забочусь об этом внутри 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
, я хочу изменить размер доски, а затем снова заполнить ее случайными «живыми» ячейками.Вот 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
, чтобы получить новый размер платы и заполнить ее случайными «живыми» ячейками для этого размера платы,так же, как я делаю изначально с 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
})
}
}
}
Доска успешно меняет размеры, когда пользователь нажимает кнопки, чтобы изменить ее размер, но не генерирует случайные«живые» квадраты, как и должно быть.Он просто изменяет высоту и ширину доски, но доска пуста.
Как я могу использовать componentDidUpdate
, чтобы заполнить игровое поле случайными «живыми» ячейками при изменении его размера (аналогично тому, что он делаетпри первоначальной установке, но подходящего размера при изменении размеров платы).componentDidUpdate
правильный подход?Является ли это проблемой с асинхронностью setState?
Я уверен, что я обдумываю это.
Вы можете проверить код на codesandbox .