I have the following function:
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;
This works, but this is always for a 3x3 matrix. I have to set this dynamic, so I thought I'll set the default state with ES6 array construction like:
const n = 4; // Will be set through props
const [matrix, setMatrix] = useState(Array(n).fill(Array(n).fill(null)));
But when I use this case and I update (type a number in an input field), the whole column in the matrix will get that number.
Can anybody explain this?
When I use this piece of code:
const [matrix, setMatrix] = useState(
Array.from({ length: 3 }, v => Array.from({ length: 3 }, v => null))
);
it works again.
Array(n).fill(null)
is evaluated once and it populates the entire array with the same reference values and hence when you update a single column, all rows are updated.
To solve this issue, you can use Array.from to create a 2D matrix like 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" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.