我试图在用户点击按钮时更新一行按钮。我的按钮存储在我映射的状态。当我使用 console.log 时,我可以看到网格状态发生变化,但它不会重新呈现我的按钮。我哪里出错了?
const Step = ({ active, changeGridByVal, val }) => {
return <>
<button onClick={() => changeGridByVal(val)}>{active ? 'X' : 'O'}</button>
</>
}
const TryPage = () => {
const [grid, setGrid] = useState([
['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
])
function changeGridByVal(val){
const note = val[0]
const step = val.substring(2)
const copy = grid
copy[note][step] = 'X'
setGrid(copy)
console.log(grid)
}
return <>
{grid[0].map((e, i) => {
return <Step key={i} val={`0-${i}`} changeGridByVal={changeGridByVal} active={e === '' ? false : true}></StepNote>
})}
</>
}
答案 0 :(得分:2)
function changeGridByVal(val){
const note = val[0]
const step = val.substring(2)
const copy = grid
copy[note][step] = 'X'
setGrid(copy)
console.log(grid)
}
copy
实际上不是副本,而是原始数组,只是名称不同。当您设置状态时,react 在旧状态和新状态之间执行 === 并看到它们是相同的数组,因此它不会重新渲染。
相反,您需要创建一个新数组,这意味着在您更改的每个级别都创建一个副本:
function changeGridByVal(val){
const note = val[0]
const step = val.substring(2)
const copy = [...grid];
copy[note] = [...grid[note]];
copy[note][step] = 'X';
setGrid(copy)
}
答案 1 :(得分:0)
尽管您创建了状态数组的“副本”,但您正在直接改变状态。但坦率地说,如果我正确理解了您的小应用程序,那么有一种更简单的方法可以将它们组合在一起。
您似乎只是想在 O 和 X 之间切换按钮。我希望您这样做:
import { useState } from "react";
const Step = ({ active, changeGridByVal, index }) => (
<button onClick={() => changeGridByVal(index)}>{active ? "X" : "O"}</button>
);
const TryPage = () => {
const [grid, setGrid] = useState([["O", "O", "O", "O", "O", "O"]]);
const changeGridByVal = (index) => {
setGrid([
grid[0].map((btn, i) => {
if (index === i) return btn === "O" ? "X" : "O";
else return btn;
})
]);
};
return (
<>
{grid[0].map((e, i) => {
return (
<Step
key={i}
index={i}
changeGridByVal={changeGridByVal}
active={e !== "O"}
></Step>
);
})}
</>
);
};
export default TryPage;
沙盒:https://codesandbox.io/s/admiring-worker-hoxyg?file=/src/App.js