我具有以下功能:
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)));
但是,当我使用这种情况并更新(在输入字段中键入数字)时,矩阵中的整个列都将获得该数字。
有人可以解释吗?
当我使用这段代码时:
const [matrix, setMatrix] = useState(
Array.from({ length: 3 }, v => Array.from({ length: 3 }, v => null))
);
它再次起作用。
答案 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" />