useState set 方法不改变我的状态 - 反应本机

问题描述 投票:0回答:1

我正在开发处理一副纸牌的应用程序的一部分。无论玩家应该拥有多少张牌,我都会循环浏览处于某种状态的一副牌,随机挑选一张牌,将其分配给该玩家,然后将其从牌组中删除。这一切都正常工作,但是当牌组为空时(.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);
    }
  }

但仍然没有运气。任何帮助或建议将不胜感激。谢谢!

javascript arrays react-native react-hooks
1个回答
0
投票

您需要了解

useEffect
state 应该如何在 React 中使用。

  1. 您不应依赖何时

    useEffect
    执行的频率。您应该仅使用它来声明哪个状态依赖于哪个其他状态(另请参阅“您可能不需要效果”)。

  2. 来自

    setState
    的“状态”(值和
    set...
    函数)应该用于例如根据其他状态或用户操作进行更新。它不应该像普通的“变量”一样使用。

当你调用

useState
时,你是在告诉 React 你希望这个组件记住一些东西

请注意,完整的

for
循环会一直运行,直到完成 before React 甚至会尝试执行
setCurrentDeck
。当
for
循环完成时,所有
set...
函数都会被执行,这实际上就像只执行了最后一个函数。

也许有一个解决方案:

我想你可能应该使用“正常”javascript 模式(也许在单独的函数中)构建新的牌组,即不使用 React 特定模式。然后,当创建甲板并且需要与用户交互并再次更新屏幕时,使用准备好的甲板更新 React 状态。

© www.soinside.com 2019 - 2024. All rights reserved.