React, кажется, выполняет две функции одновременно

Я сделал простую игру камень-ножницы-бумага. Во время onclick я вызываю функцию для добавления числа и изменения состояния. Затем внутри этой функции я вызываю еще 2 функции: одна выбирает случайное число от 1 до 3, преобразует его в камень/ножницы/бумагу и присваивает его состоянию, а затем другая функция определяет, кто выиграл:

addToInput = val =>{
    this.setState({ 
        input:val
    });

    this.picknum();
    this.pickwin();       
}

https://codepen.io/russiandobby/pen/xeRYzw?editors=0002

Сначала я думал, что picknum и pickwin будут выполняться одновременно, однако, даже если я попытаюсь вызвать pickwin внутри picknum, это все равно не сработает.

Кажется, что когда pickwin выполняется, он смотрит на старое состояние, а не на состояние, которое изменяется picknum.

Как я могу решить эту проблему?

покажи свой забавный код picknum() и pickwind()..

sathish kumar 10.04.2019 05:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
154
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это асинхронный механизм javascript

 this.setState({ 

    input:val


  });

если вы хотите синхронизироваться. Давайте использовать async/await. вот мой код:

 addToInput = async val =>{
   // console.info('add function');

 await this.setState({ 

    input:val


  });
   await this.picknum();
  await this.pickwin();

 } 

Давай попробуй!

Это правда, что setState является (или может быть) асинхронным, но он не возвращает промис, поэтому ожидание не поможет.

Nicholas Tower 10.04.2019 05:10

Кажется, проблема исправлена, если я что-то упустил

russiandobby 10.04.2019 05:17

Ожидание не-обещания только задержит код до следующей микрозадачи и не гарантирует, что он дождется того, чего, по вашему мнению, вы ждете. Если добавление await решило проблему, то вам повезло. Это неправильный способ решить проблему такого рода.

Nicholas Tower 10.04.2019 05:18

тогда как можно решить эту проблему. я думаю, если бы все было показано в одной функции и использовалось бы только одно setstate, это бы исправило это, но есть ли другой способ это исправить

russiandobby 10.04.2019 05:22
Ответ принят как подходящий

setState является асинхронным (или, по крайней мере, может быть), поэтому нет гарантии, что состояние было обновлено, когда вы переходите к следующим строкам кода. Если вам нужно что-то запустить после установки состояния, либо поместите его в Обработчик жизненного цикла componentDidUpdate или передать обратный вызов в setState в качестве второго параметра.

Например, вы можете пропустить pickWin в своей функции addToInput и вместо этого иметь функцию componentDidUpdate, подобную этой:

componentDidUpdate(prevProps, prevState) {
  this.pickWin();
}

Тем не менее, вместо того, чтобы устанавливать состояние, затем ждать его обновления, а затем снова устанавливать состояние, я бы рекомендовал вам реорганизовать свой код, чтобы просто вызвать setState один раз. Если вы вызываете его несколько раз, у вас есть возможность вызвать несколько рендеров, но похоже, что все они предназначены для того, чтобы быть частью одной и той же операции. Возможно, обновите свои функции pickNum и pickWin, чтобы они возвращали значение, а не устанавливали само состояние, а затем вызывайте setState один раз с результатами.

picknum () {
  let aipick = ["rock","paper","scisors"];   
  let temp = Math.floor(Math.random() * 3) + 0  ;
  return aipick[temp]
}

pickWin(userChoice, aiChoice) {
  if (userChoice === 'rock' && aiChoice == 'scisors') {
    return 'USER WINS';
  }
  // etc
}

addToInput = val => {
  let aiChoice = pickNum();
  let winner = pickWin(val, aiNum);
  this.setState({
    aiChoice: aiChoice,
    whowon: winner,
    input: val,
  })
}

Спасибо, я попытался сделать обратный вызов, и теперь он работает.

russiandobby 10.04.2019 05:41

Итак, кажется, что обратные вызовы могут быть одним из решений, поэтому я пытался сделать это

  picknum (){

     let aipick=["rock","paper","scisors"];   
      let temp =Math.floor(Math.random() * 3) + 0  ;
  this.setState({
    aichoice:aipick[temp]
  },function(){
   this.pickwin();
 }
               )


}




  ////////////
addToInput = val =>{
   // console.info('add function');

 this.setState({ 

    input:val


  },function(){
   this.picknum();
 }

              );


 } 

кажется, работает сейчас.

Другие вопросы по теме