Реакция - Game of Life - Обновление состояния определенных элементов в 2D-массиве в зависимости от того, какие элементы были нажаты пользователем - PullRequest
0 голосов
/ 21 сентября 2018

Я все еще изучаю React и работаю над кодированием «Игры жизни» Джона Конвея.Я создал игровую доску для игры, используя 2D массив в состоянии.У меня есть этот двумерный массив в состоянии в моем App.js.У меня также есть два функциональных компонента: Gameboard.js и Square.js получение реквизита и создание игрового поля.

Gameboard.js создает таблицу и передает реквизиты на Square.js, давая ему знать, какие квадраты должны быть выделены икоторый не долженДругими словами, он дает каждому отдельному квадрату знать, нажал ли он на него пользователем и «жив» ли он в смысле Игры Жизни.

После того, как пользователь щелкнул конкретный квадрат в Square.js, у меня есть функция обратного вызовасрабатывает по клику.Функция обратного вызова aliveCallback передает координаты X и Y определенного квадрата, по которому был выполнен щелчок, обратно на App.js.App.js вызывает функцию с именем alive.

Когда вызывается alive, мне нужно обновить состояние двумерного массива, чтобы конкретный квадрат (это координаты X и Y, например, [0, 0] или [0, 1] и т. Д.)..) устанавливается в логическое значение, сохраненное в состоянии.Затем это логическое значение может быть передано в Gameboard.js как isAlive.Затем игровое поле передает значение isAlive в Square.js, а Square.js имеет условный рендеринг, который указывает, что отдельный квадрат должен быть выделен светло-голубым.

Это был полный рот, и, вероятно, это было бы проще всего проверить коды и увидеть структуру проекта .Также полезно упомянуть, что я следую совету, который постер SO дал мне в этом посте .

После прочтения и просмотра документов 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, а затем попытаться установить в значение true для этого конкретного квадрата.

1 Ответ

0 голосов
/ 21 сентября 2018

Я думаю, что проблема в том, что у вас есть переменная состояния 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, чтобы было более ясно, что это метод, который что-то делает.

Edit :

Если вы хотитенажмите или, чтобы сделать ячейку живой или мертвой в зависимости от ее текущего состояния, вы можете изменить строку:

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

на

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

Выглядит как классное приложение, кстати.

...