react useState落后一步的问题

我正在尝试将我从 Udemy 学到的 Javascript 游戏转换为反应应用程序。它显然称为 Pig-Game。您可以掷骰子并将其值添加到您的银行中,直到您击中 1,然后轮到您的对手掷骰子。您可以在轮到您之前持有该价值并将其添加到您的总数中。我为“btn-roll”编写了一个函数来更新骰子并将其值添加到我的状态中。这是代码(排除不必要的部分):


const App = () => {


  const [dice, setdice] = useState(null);

  const [current, setCurrent] = useState(0);

  const [activePlayer, setactivePlayer] = useState(0);


  const diceHandler = () => {

    if (dice !== 1) {

      setdice(() => {

        const _dice = (Math.floor(Math.random() * 6) + 1);

        setCurrent(current + _dice);

        console.log(_dice);

        return _dice;

      }

      );

    } else {

      activePlayer === 0 ? setactivePlayer(1) : setactivePlayer(0);

      setdice(() => {

        setCurrent(0);

        return null;

      })

    }

  }


 return (


      <button className="btn-roll" onClick={diceHandler}><i className="ion-ios-loop"></i>Roll dice</button>

      {dice ?

        <img src={require(`./dice-${dice}.png`)} alt="Dice" className="dice" /> :

        <></>

      }

  );

第一个问题是“骰子”和“电流”落后了一步。每次我单击按钮时,它都会显示随机骰子图片,但骰子和电流的实际值落后 1 步。我用你目前看到的代码修复了它。现在的问题是,一旦我点击“1”,它会将值添加到当前,然后我必须再次单击,以便启动“setCurrent(0)”并切换 activePlayer。我也试过这个功能,但结果是一样的:


  const diceHandler = () => {


    setdice(() => {

      if (dice !== 1) {

        const _dice = (Math.floor(Math.random() * 6) + 1);

        setCurrent(current + _dice);

        console.log(_dice);

        return _dice;

      } else {

        activePlayer === 0 ? setactivePlayer(1) : setactivePlayer(0);

        setdice(() => {

          setCurrent(0);

          return null;

        })

      }

    }

    );


  }

我想知道我现有的功能(用于更新状态)是否有更好的解决方案以及为什么我必须再次单击该按钮。我使用 Hooks 完全错误吗?提前致谢


慕码人8056858
浏览 141回答 2
2回答

MYYA

您也许可以稍微简化该逻辑。&nbsp;const diceHandler = () => {&nbsp; &nbsp;const _dice = Math.floor(Math.random() * 6) + 1;&nbsp; &nbsp;&nbsp; &nbsp;if (_dice !== 1) {&nbsp; &nbsp; &nbsp;setCurrent(current + _dice);&nbsp; &nbsp; &nbsp;setdice(_dice);&nbsp; &nbsp;} else {&nbsp; &nbsp; &nbsp;setactivePlayer(activePlayer === 0 ? 1 : 0);&nbsp; &nbsp; &nbsp;setCurrent(0);&nbsp; &nbsp; &nbsp;setdice(0);&nbsp; &nbsp;}&nbsp;};请注意如何使用三元运算符来更新 activePlayer。在状态设置器中使用回调函数有时是必要的,但在这里似乎没有必要。

富国沪深

希望下面的代码对你有帮助!&nbsp;const App = () => {&nbsp; &nbsp; &nbsp; const [dice, setdice] = useState(null);&nbsp; &nbsp; &nbsp; const [current, setCurrent] = useState(0);&nbsp; &nbsp; &nbsp; const [activePlayer, setactivePlayer] = useState(0);&nbsp; &nbsp; const stateUpdater = _dice => {&nbsp; &nbsp; &nbsp; console.log(dice);&nbsp; &nbsp; &nbsp; if (dice !== 1) {&nbsp; &nbsp; &nbsp; &nbsp; setCurrent(current + _dice);&nbsp; &nbsp; &nbsp; &nbsp; console.log("dice value " + _dice);&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; console.log("Dice value is now one!", dice);&nbsp; &nbsp; &nbsp; &nbsp; activePlayer === 0 ? setactivePlayer(1) : setactivePlayer(0);&nbsp; &nbsp; &nbsp; &nbsp; setCurrent(0);&nbsp; &nbsp; &nbsp; &nbsp; setdice(null);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };&nbsp; &nbsp; const diceHandler = () => {&nbsp; &nbsp; &nbsp; let _dice = Math.floor(Math.random() * 6) + 1;&nbsp; &nbsp; &nbsp; setdice(_dice, stateUpdater(dice));&nbsp; &nbsp; };&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp;<button className="btn-roll" onClick={diceHandler}><i className="ion-ios-loop"></i>Roll dice</button>&nbsp; &nbsp; &nbsp;{dice ?&nbsp; &nbsp; &nbsp; <img src={require(`./dice-${dice}.png`)} alt="Dice" className="dice" /> :&nbsp; &nbsp; <></>&nbsp; }&nbsp; );};diceHandler 函数只负责生成 dice 的新值并将其更新到 dice 挂钩。一旦钩子更新,就会调用回调,它的职责是在需要的地方更新值并进一步推进游戏。它之前不能工作的原因是 setState 函数是异步的并且有延迟。这就是为什么更新变量的值可能不会立即反映在 setState 之后的语句中。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript