我正在构建一个小型记忆游戏来学习 React。这个想法是你点击一个瓷砖,它被洗牌,然后你尝试选择一个你还没有选择的。问题是我似乎无法获得之前看到更新的图块的内部状态。
这是我的组件:
const Gameboard = (props) => {
const [tiles, setTiles] = useState([]);
const [currentScore, setCurrentScore] = useState(0);
const [highScore, setHighScore] = useState(0);
const [previouslySeen, setPreviouslySeen] = useState([]);
const handleClick = (evt) => {
const tile = evt.target;
if (!previouslySeen.includes(tile)) {
setCurrentScore(current => current + 1);
props.setCurrentScore(current => current + 1);
setPreviouslySeen([...previouslySeen, tile]);
} else {
alert("Game over, thanks for playing!");
if (currentScore > highScore) {
setHighScore(currentScore);
props.setHighScore(currentScore);
}
setCurrentScore(0);
props.setCurrentScore(0);
setPreviouslySeen([]);
}
};
const generateTiles = (tileCount) => {
return [...Array(tileCount).keys()].map((n) => {
return <Tile key={n} number={n} handleClick={handleClick} />;
});
};
const shuffleTiles = (tiles) => {
let tilesCopy = [...tiles];
for (let i = tilesCopy.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * i);
const temp = tilesCopy[i];
tilesCopy[i] = tilesCopy[j];
tilesCopy[j] = temp;
}
return tilesCopy;
};
useEffect(() => {
const initialTiles = generateTiles(props.tileCount);
setTiles(shuffleTiles(initialTiles));
}, []);
useEffect(() => {
setTiles((oldTiles) => {
const newTiles = shuffleTiles(oldTiles);
return newTiles;
});
}, [currentScore, highScore]);
return <div className="Gameboard">{tiles}</div>;
};
handleClick
方法被传递到各个 Tile
组件中,并且只是通过 onClick
调用。 handleClick method is what is giving me trouble, it seems as if it doesn't ever update
previouslySeen` 和我在设置父组件中的高分以使其反映在 UI 中时遇到了类似的问题。你应该如何在 React 中处理这样的更新?
答案 0 :(得分:1)
试试这个:
const handleClick = (evt) => {
const tile = evt.target;
if (!previouslySeen.includes(tile)) {
setCurrentScore(current => current + 1);
props.setCurrentScore(current => current + 1);
// Change the following line:
setPreviouslySeen(previousState => [...previousState, tile]);
} else {
此外,您从父属性和声明状态中获得 setCurrentScore, setHighScore
:
const [currentScore, setCurrentScore] = useState(0);
const [highScore, setHighScore] = useState(0);
所以本质上,您保持了两个单独的 currentScore
和 highScore
状态 - 一个在 Gameboard
组件中,一个在其父组件中。最好从 Gameboard
中删除这些状态变量和 setter,并直接从父 props 中获取它们。
答案 1 :(得分:0)
原来是因为我把JSX元素直接存储在状态中。删除它并仅存储 tile 值(纯 JS 字符串)修复了状态未正确更新的问题。相当有问题!