首页 > 解决方案 > 在用户生成的多维数组中选择项目,整列被选中

问题描述

我正在构建一个应用程序,用户可以在其中输入高度和宽度并生成具有这些尺寸的网格。然后,当单击单个单元格时,他们可以打开或关闭它们。我使用多维数组来显示每个单元格的单独状态。

单击每个单元格时,坐标将传递给更新多维数组状态的更新器方法。我遇到的问题是,当单击一个项目时,整个列都会被切换。

单击 3x3 多维数组中的坐标第 0 列和第 0 行时

预期新的更新数组

[
[true, false, false],
[false, false, false],
[false, false, false]
]

电流输出:

[
[true, false, false],
[true, false, false],
[true, false, false]
]

我检查了是否传递了正确的坐标并且它们是正确的。似乎只有当我对多维数组进行硬编码时才能解决问题。我相信当我使用输入坐标生成网格时会出现问题。

import { useState } from 'react';
import './style.css';

import Grid from '../Grid';
import InputView from '../InputView';
import Navigation from '../Navigation';

const App = () => {
  const [inputView, setInputView] = useState({ visible: true, rebuildingGrid: false });
  const [gridSize, setGridSize] = useState({ width: 0, height: 0 });
  const [prevGridSize, setPrevGridSize] = useState(undefined);
  const [gridMatrix, setGridMatrix] = useState(undefined);

  const generateGrid = (size) => {
    var grid = [];
    var row = [];
    for(let i=0; i<size.width; i++) row.push(false);
    for(let j=0; j<size.height; j++) grid.push(row); 
    setGridMatrix(grid);

    // works hard coded
    // var test = [
    //   [false, false, false],
    //   [false, false, false],
    //   [false, false, false],
    // ];
    //  setGridMatrix(test);
  };

  const inputNewGrid = () => {
    setInputView({ visible: true, rebuildingGrid: true });
    setPrevGridSize(gridSize);
  };

  const toggleCell = (coords) => {
    var { row, col } = coords;
    var newGridMatrix = [...gridMatrix];
    newGridMatrix[row][col] = newGridMatrix[row][col] === false ? true : false;
    setGridMatrix(newGridMatrix);
    console.log(newGridMatrix);
  } 

  return (
    <>
      <div onClick={() => console.log(gridMatrix)}>
        <h1>
          LOG MATRIX
        </h1>
      </div>
      { inputView.visible ? 
        <InputView 
          gridSize={gridSize}
          prevGridSize={prevGridSize}
          setGridSize={setGridSize}
          setInputView={setInputView} 
          generateGrid={() => generateGrid(gridSize)}
          rebuildingGrid={inputView.rebuildingGrid} 
        />
      : 
      (
        <>
          <Navigation inputNewGrid={inputNewGrid} />
          <Grid gridSize={gridSize} gridMatrix={gridMatrix} toggleCell={toggleCell} />
        </>
      )}
    </>
  );
}

export default App;

标签: javascriptreactjs

解决方案


问题是您将数组row推入网格。因此,网格内的每一行都“链接到”/引用同一个数组=>如果你改变一行,每一行都会改变。要解决此问题,您必须在row每次要将其推入网格时重新声明/重新分配变量。

解决方案将像这样生成您的网格:

// if you want it to be one line
var grid = Array.from(Array(size.height)).map(() => Array(size.width).fill(false));

// other option
var grid = [];

for (let j = 0; j < size.height; j++) {
  var row = [];
  for (let i = 0; i < size.width; i++) row.push(false);
  // another option would be:
  // var row = new Array(size.width).fill(false); < the "new" isn't necessary, but I think it looks better that way
  grid.push(row);
}

推荐阅读