亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

react useState落后一步的問題

react useState落后一步的問題

慕碼人8056858 2022-11-11 13:49:41
我正在嘗試將我從 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 完全錯誤嗎?提前致謝
查看完整描述

2 回答

?
MYYA

TA貢獻1868條經驗 獲得超4個贊

您也許可以稍微簡化該邏輯。


 const diceHandler = () => {

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

   

   if (_dice !== 1) {

     setCurrent(current + _dice);

     setdice(_dice);

   } else {

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

     setCurrent(0);

     setdice(0);

   }

 };

請注意如何使用三元運算符來更新 activePlayer。在狀態設置器中使用回調函數有時是必要的,但在這里似乎沒有必要。


查看完整回答
反對 回復 2022-11-11
?
富國滬深

TA貢獻1790條經驗 獲得超9個贊

希望下面的代碼對你有幫助!


 const App = () => {

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

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

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


    const stateUpdater = _dice => {

      console.log(dice);

      if (dice !== 1) {

        setCurrent(current + _dice);

        console.log("dice value " + _dice);

      } else {

        console.log("Dice value is now one!", dice);

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

        setCurrent(0);

        setdice(null);

      }

    };


    const diceHandler = () => {

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

      setdice(_dice, stateUpdater(dice));

    };


    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" /> :

    <></>

  }

  );

};

diceHandler 函數只負責生成 dice 的新值并將其更新到 dice 掛鉤。


一旦鉤子更新,就會調用回調,它的職責是在需要的地方更新值并進一步推進游戲。


它之前不能工作的原因是 setState 函數是異步的并且有延遲。這就是為什么更新變量的值可能不會立即反映在 setState 之后的語句中。


查看完整回答
反對 回復 2022-11-11
  • 2 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號