在React

时间:2019-12-09 13:19:38

标签: javascript reactjs

我具有以下功能:

import React, { useState } from "react";

const Sheet = () => {
  const [matrix, setMatrix] = useState([
    [null, null, null],
    [null, null, null],
    [null, null, null]
  ]);

  const handleChange = (row, column, event) => {
    let copy = [...matrix];
    copy[row][column] = +event.target.value;
    setMatrix(copy);

    console.log(matrix);
  };

  return (
    <div className="sheet">
      <table>
        <tbody>
          {matrix.map((row, rowIndex) => (
            <tr key={rowIndex}>
              {row.map((column, columnIndex) => (
                <td key={columnIndex}>
                  <input
                    type="number"
                    onChange={e => handleChange(rowIndex, columnIndex, e)}
                  />
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default Sheet;

这有效,但这始终适用于3x3矩阵。我必须设置此动态,所以我想用ES6数组构造来设置默认状态,例如:

const n = 4; // Will be set through props
const [matrix, setMatrix] = useState(Array(n).fill(Array(n).fill(null)));

但是,当我使用这种情况并更新(在输入字段中键入数字)时,矩阵中的整个列都将获得该数字。

Matrix should update only matrix[0][0]

Updates all first items of each row

有人可以解释吗?

当我使用这段代码时:

const [matrix, setMatrix] = useState(
    Array.from({ length: 3 }, v => Array.from({ length: 3 }, v => null))
  );

它再次起作用。

1 个答案:

答案 0 :(得分:0)

Array(n).fill(null)进行一次评估,并使用相同的参考值填充整个数组,因此,当您更新单个列时,所有行都会更新。

要解决此问题,您可以使用Array.from创建2D矩阵,例如Array.from({length: n},()=> Array.from({length: n}, () => null))

const { useState } = React;

const n = 4;
const Sheet = () => {
  const [matrix, setMatrix] = useState(Array.from({length: n},()=> Array.from({length: n}, () => null)));

  const handleChange = (row, column, event) => {
    let copy = [...matrix];
    copy[row][column] = +event.target.value;
    setMatrix(copy);

    console.log(matrix);
  };

  return (
    <div className="sheet">
      <table>
        <tbody>
          {matrix.map((row, rowIndex) => (
            <tr key={rowIndex}>
              {row.map((column, columnIndex) => (
                <td key={columnIndex}>
                  <input
                    type="number"
                    onChange={e => handleChange(rowIndex, columnIndex, e)}
                  />
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

ReactDOM.render(<Sheet />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />