我正在开发处理一副纸牌的应用程序的一部分。无论玩家应该拥有多少张牌,我都会循环浏览处于某种状态的一副牌,随机挑选一张牌,将其分配给该玩家,然后将其从牌组中删除。这一切都正常工作,但是当牌组为空时(.length === 0),我想调用 shuffle() 方法,该方法将把牌组设置为等于丢弃堆,丢弃堆也是保存在 useState 中的数组。丢弃堆也按预期工作,但由于某种原因,当尝试使用 setCurrentDeck(discardPile) 将 currentDeck 设置为丢弃堆时,currentDeck 数组仍为空。 (我也尝试过 setCurrentDeck([...discardPile]))。
我知道这很可能与 React 如何处理批处理钩子调用有关,并且 currentDeck 的值不是我想象的那样,因为其他 setCurrentDeck() 调用,但我仍然无法弄清楚是什么正在进行中。
我的代码(简化):
const [currentDeck, setCurrentDeck] = useState(deck) // 'deck' is a hard coded array of cards
const [discardPile, setDiscardPile] = useState([])
const [faceUpCard, setFaceUpCard] = useState(null)
useEffect(() => {
if (currentDeck.length === 0) {
const temp = discardPile;
setCurrentDeck([...temp]);
setDiscardPile([]);
}
}, [currentDeck]);
function deal() {
if (readyToDeal) {
for (let i = 0; i < round + 2; i++) {
for (let j = 0; j < players.length; j++) {
const rand = Math.floor(Math.random() * currentDeck.length);
// players are assigned cards
currentDeck.splice(rand, 1); // card that was assigned is removed from deck
setCurrentDeck([...currentDeck]);
}
}
const rand = Math.floor(Math.random() * currentDeck.length);
setFaceUpCard(currentDeck[rand]);
currentDeck.splice(rand, 1);
setCurrentDeck([...currentDeck]);
setReadyToDeal(false);
}
}
我也尝试过使用这样的随机播放方法设置 currentDeck:
function shuffle() {
const temp = discardPile;
setCurrentDeck([ ...temp]);
setDiscardPile([]);
}
function deal() {
if (readyToDeal) {
for (let i = 0; i < round + 2; i++) {
for (let j = 0; j < players.length; j++) {
if (currentDeck.length === 0) {
shuffle();
}
const rand = Math.floor(Math.random() * currentDeck.length);
// players are assigned cards
currentDeck.splice(rand, 1); // card that was assigned is removed from deck
setCurrentDeck([...currentDeck]);
}
}
const rand = Math.floor(Math.random() * currentDeck.length);
setFaceUpCard(currentDeck[rand]);
currentDeck.splice(rand, 1);
setCurrentDeck([...currentDeck]);
setReadyToDeal(false);
}
}
但仍然没有运气。任何帮助或建议将不胜感激。谢谢!
useEffect
和 state 应该如何在 React 中使用。
您不应依赖何时或
useEffect
执行的频率。您应该仅使用它来声明哪个状态依赖于哪个其他状态(另请参阅“您可能不需要效果”)。
来自
setState
的“状态”(值和 set...
函数)应该用于例如根据其他状态或用户操作进行更新。它不应该像普通的“变量”一样使用。
当你调用
时,你是在告诉 React 你希望这个组件记住一些东西useState
请注意,完整的
for
循环会一直运行,直到完成 before React 甚至会尝试执行 setCurrentDeck
。当 for
循环完成时,所有 set...
函数都会被执行,这实际上就像只执行了最后一个函数。
我想你可能应该使用“正常”javascript 模式(也许在单独的函数中)构建新的牌组,即不使用 React 特定模式。然后,当创建甲板并且需要与用户交互并再次更新屏幕时,使用准备好的甲板更新 React 状态。