更新反应 useState 挂钩嵌套二维数组

Updating react useState hook nested 2d array

  1. 嗨,我正在尝试更新嵌套的 2d 板字段状态,但没有成功。

有没有更简单的方法来存储二维数组?

export default function Game() {
    const [state, setState] = useState({
        board: [
            [null, "B", null, "B", null, "B", null, "B"],
            ["B", null, "B", null, "B", null, "B", null],
            [null, "B", null, "B", null, "B", null, "B"],
            ["X", null, "X", null, "X", null, "X", null],
            [null, "X", null, "X", null, "X", null, "X"],
            ["G", null, "G", null, "G", null, "G", null],
            [null, "G", null, "G", null, "G", null, "G"],
            ["G", null, "G", null, "G", null, "G", null],
        ],
        greyTurn: true,
        chess: null,
        dest: null,
    });




const update = () => {
        setState(prevState => ({...prevState, board[0,0]: 'G'}))
    }


return (
<>
   <button onClick={update}></button>
<>
)
  1. 更新功能改成这个

const update = () => { const newState = [...state.board]; newState[0][0] = 'G'; }

居然做了update state,但是我不明白为什么,我不是直接创建了deep state.board copy吗?为什么操纵这个深层副本实际上会改变我的 state.board?

你的状态是一个对象,你的棋盘是那个对象的 属性。当你这样做时:

setState(prevState => ({...prevState, board[0,0]: 'G'})

您正在尝试将值 Gboard[0,0](这将引发错误)属性 设置为您的 state,而不是修改您的 board数组。

您需要先复制您的电路板。您还可以复制要修改的嵌套数组。那么你可以 return 你的下一个状态为:

    setState(prevState => {
      const newBoard = [...prevState.board];
      newBoard[0] = [...newBoard[0]];
      newBoard[0,0] = 'G';
      return { ...prevState, board: newBoard }
    })

使用钩子,您可以将状态分解为多个状态,而不是将所有状态存储在一个状态对象中。独立处理状态片段会更好。

无论如何,要更新数组,您仍然需要创建一个副本然后更改所需的索引:

export default function Game() {
    const [board, setBoard] = useState([
            [null, "B", null, "B", null, "B", null, "B"],
            ["B", null, "B", null, "B", null, "B", null],
            [null, "B", null, "B", null, "B", null, "B"],
            ["X", null, "X", null, "X", null, "X", null],
            [null, "X", null, "X", null, "X", null, "X"],
            ["G", null, "G", null, "G", null, "G", null],
            [null, "G", null, "G", null, "G", null, "G"],
            ["G", null, "G", null, "G", null, "G", null],
        ]);
    const [greyTurn, setgreyTurn] = useState(true);
    const [chess, setChess] = useState(null);
    const [dest, setDest] = useState(null);

    const updateBoard = () => {
        setBoard(prevBoard => {
          const board = [...prevBoard];
          board[0] = [...board[0]];
          board[0,0] = 'G';
          return board;
        })
    }
    

import React, {useState} from 'react';

export default function Game() {
  const [state, setState] = useState({
    board: [
      [null, 'B', null, 'B', null, 'B', null, 'B'],
      ['B', null, 'B', null, 'B', null, 'B', null],
      [null, 'B', null, 'B', null, 'B', null, 'B'],
      ['X', null, 'X', null, 'X', null, 'X', null],
      [null, 'X', null, 'X', null, 'X', null, 'X'],
      ['G', null, 'G', null, 'G', null, 'G', null],
      [null, 'G', null, 'G', null, 'G', null, 'G'],
      ['G', null, 'G', null, 'G', null, 'G', null],
    ],
    greyTurn: true,
    chess: null,
    dest: null,
  });

  const update = () => {
    setState((prevState) => {
      const { board } = prevState;
      board[0][0] = 'G';
      return { ...prevState, board };
    });
  };

  return (
    <>
      <button onClick={update}></button>
    </>
  );
}

这是更新棋盘中第一个数组的第一个索引的方法。