Рендеринг состояния на основе условия с помощью Hooks (Создание простой игры с ножницами из каменной бумаги) - PullRequest
2 голосов
/ 29 марта 2020

Я пытаюсь выучить хуки в React. js переписывая игру "Rock Paper Scissor". Я не могу оценить победителя одновременно с нажатием кнопки выбора. Это мой код (это более короткий код, в котором я сравниваю только плеер, нажимающий кнопку бумаги):

function App() {
  const weapons = ["paper","scissors","rock"];


  const [choice, setChoice] = useState({
    playerOne: "",
    playerTwo: "",
    winner: ""
  })




  const chooseWeapon=(weapon)=>{
    setChoice({
      playerOne: weapon,
      playerTwo: weapons[Math.floor(Math.random() * 3)],
      winner: getWinner(choice.playerOne,choice.playerTwo)

    })



  }


  const getWinner = (player1,player2)=>{
    if(player1==="paper"){
      if(player2==="scissors"){
       return("player two won")
      } else if(player2==="rock"){
       return("player one won!!!!!")
      }
    }
  }

  return (
    <div className="App">
     <h1>Rock scissors lizard</h1>
     <h2>player one:{choice.playerOne}</h2>
     <h2>player two:{choice.playerTwo}</h2>
     <h1>{choice.winner}</h1>

     <button onClick={()=>chooseWeapon("paper")}>paper</button>
     <button onClick={()=>chooseWeapon("scissors")}>scissors</button>
     <button onClick={()=>chooseWeapon("rock")}>rock</button>
    </div>
  );
}

export default App;

В основном, когда я нажимаю кнопку «бумага», меня визуализируют на экране выбора каждого из них. игрок, но я получу статус победителя только после повторного нажатия. Победитель рендера всегда на шаг позади. Как я могу это исправить?

Спасибо, ребята!

Ответы [ 2 ]

4 голосов
/ 29 марта 2020

Обновления состояния происходят не сразу, а в следующем цикле рендеринга, поэтому, когда вы ожидаете, что переменная победителя будет оценена на основе выбора игрока 1 и игрока 2, она фактически будет основана на предыдущем значении. Чтобы решить эту проблему, вам нужно сначала вычислить победителя, а затем установить его в состояние

function App() {
  const weapons = ["paper","scissors","rock"];


  const [choice, setChoice] = useState({
    playerOne: "",
    playerTwo: "",
    winner: ""
  })




  const chooseWeapon=(weapon)=>{
    const choiceP1 = weapon;
    const choiceP2 = weapons[Math.floor(Math.random() * 3)];
    const winner = getWinner(choiceP1, choiceP2)
    setChoice({
      playerOne: choiceP1,
      playerTwo: choiceP2,
      winner,
    })
  }


  const getWinner = (player1,player2)=>{
    if(player1==="paper"){
      if(player2==="scissors"){
       return("player two won")
      } else if(player2==="rock"){
       return("player one won!!!!!")
      }
    }
  }

  return (
    <div className="App">
     <h1>Rock scissors lizard</h1>
  <h2>player one:{choice.playerOne}</h2>
  <h2>player two:{choice.playerTwo}</h2>
  <h1>{choice.winner}</h1>

     <button onClick={()=>chooseWeapon("paper")}>paper</button>
     <button onClick={()=>chooseWeapon("scissors")}>scissors</button>
     <button onClick={()=>chooseWeapon("rock")}>rock</button>
    </div>
  );
}

export default App;
3 голосов
/ 29 марта 2020

В функции, в которой вы передаете аргументы для определения победителя игры:

setChoice({
  playerOne: weapon,
  playerTwo: weapons[Math.floor(Math.random() * 3)],
  winner: getWinner(choice.playerOne,choice.playerTwo)
})

здесь, choice.playerOne и choice.player2, на которые вы ссылаетесь, еще не установлены. Что вам нужно сделать, это передать текущие варианты выбора playerOne и playerTwo.

const playerOne = weapon;
const playerTwo = weapons[Math.floor(Math.random() * 3)];
setChoice({
  playerOne,
  playerTwo,
  winner: getWinner(playerOne, playerTwo),
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...