Реагируйте useState с «глубоким» массивом, не переназначая компоненты

#javascript #reactjs

Вопрос:

У меня есть 2D-массив, хранящийся useState() в React. Когда я обновляю одно из значений в массиве (создаю совершенно новый 2D-массив, он фактически не перерисовывает мой компонент с новыми значениями. Компонент обновляется только в том случае, если я делаю что-то еще после обновления 2D-массива, который вызывает компонент

Мой массив определен следующим образом:

 const [grid, setGrid] = useState([
    ['', '', ''],
    ['', '', ''],
    ['', '', '']
  ]
 

И я обновляю его вот так

     setGrid(prevGrid => {
      const newRow = prevGrid[posy]
      newRow[posx] = currentPlayer
      const newGrid = prevGrid
      newGrid[posy] = newRow
      return newGrid
    }
 

И, наконец, я использую его в таких компонентах, как этот:

 <Square status={grid} y={2} x={0} clickEvent={() => handleBoxClick(2, 0)} /
 

Я подозревал, что проблема связана с «глубиной» объекта состояния, но я не думаю, что у React те же проблемы с не обнаружением глубоких обновлений, что и у Vue. (Я в прошлом разработчик Vue) Итак, я полагаю, что я делаю что-то не так здесь с обновлением состояния.

Спасибо

Ответ №1:

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

 setGrid(prevGrid => {
  const newRow = [...prevGrid[posy]]
  newRow[posx] = currentPlayer
  const newGrid = [...prevGrid]
  newGrid[posy] = newRow
  return newGrid
}