【发布时间】:2021-11-25 07:20:45
【问题描述】:
我正在尝试更新一个 20x20 值的矩阵,每个插槽都绑定到一个 div,一旦单击一个 div,它的背景颜色应该会改变。
在不必设置整个矩阵的情况下,最好的方法是什么?
另外,为什么有些 set 方法不起作用,因为大多数这些方法都是通过互联网在示例中使用的?
import { useState } from "react";
function App() {
const n = 20;
// define [20][20] array with default value on each slot as { color: "red" }
const [matrix, setMatrix] = useState(Array(n).fill(Array(n).fill({ color: "red" })))
let updateCell = (i, j) => {
console.log(i, j); // Works perfectly, returns i and j of the matrix slot binded to the clicked cell.
// const mat = matrix; mat[i][j].color = "blue"; // Doesnt work
// setMatrix((mat) => { mat[i][j].color = "blue"; return mat; }); // Doesnt work
// matrix[i][j].color = "blue"; setMatrix(matrix); // Doesnt work
// matrix[i][j].color = "blue"; setMatrix([...matrix]); // Changes ALL squares instead of the one clicked.
// const mat = Object.assign({}, matrix); setMatrix(mat); // TypeError: matrix.map is not a function
}
return (
<div className="container">
{/* Renders all squares fine! */}
{matrix.map((i, ipos) => {
console.log(matrix.length);
return (
<div key={ipos} className="d-flex flex-row wrap">
{i.map((j, jpos) => {
console.log(i.length);
return (
<div
style={{ backgroundColor: matrix[ipos][jpos].color, minWidth: "5%", minHeight: "50px", textAlign: "center", color: "white" }}
key={ipos + ", " + jpos}
onClick={() => { updateCell(ipos, jpos) }}
>
{ipos + ", " + jpos}
</div>
)
})}
</div>
)
})}
</div>
)
}
export default App;
最好的问候,谢谢。
【问题讨论】:
-
你正在改变状态; React 不会更新组件,除非它是一个全新的矩阵数组。第四种变体也应该没有效果。第五个将矩阵从数组更改为对象,它们没有映射函数,因为它们不是数组。
-
@Chris G 我也尝试过该解决方案以及其他一些解决方案,但我找不到太多,大多数解决方案都行不通,或者如果可以,它会仅单击一个时更改所有单元格的颜色。此外,第四个变体由于某种原因改变了所有单元格的颜色,我可以肯定地说,因为我刚刚尝试过这些。不过感谢您的帮助!
-
是的,问题是你如何填充数组。
{ color: "red" }创建一个 single 对象,并且所有数组元素都包含/指向该单个对象。更改颜色属性将对所有元素执行此操作。 -
你需要像这样填充和映射:jsfiddle.net/85dfb3vx
标签: javascript reactjs use-state