不同函数中状态变量的值不同 [英] Value of a state variable different in a different function

查看:0
本文介绍了不同函数中状态变量的值不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搞不懂作用域在Reaction中的工作原理。

我想将一个状态的值传递给另一个状态,但我发现在一个函数中它打印了正确的值,而在另一个函数中却没有。

这是一个倒计时,计时器倒计时并计算点击量,最后,我想要获得总点击量并将其发送到总状态。因此,状态为:

  const [strokeScore, setStrokeScore] = useState(1);

  const [totalStrokeScore, setTotalStrokeScore] = useState(1);

  const [strokeCountdown, setStrokeCountdown] = useState();

strokeScore是游戏中的点击量--我想得到总点击数,并将其计入总击球分数。

由于某种原因,我无法执行此操作-这是怎么回事?

import React, { useEffect, useState } from 'react';

function ScoreCard() {

  const [strokeScore, setStrokeScore] = useState(1);

  const [totalStrokeScore, setTotalStrokeScore] = useState(1);

  const [strokeCountdown, setStrokeCountdown] = useState();

  const strokeCountdownDing = new Audio('/sounds/round-complete.mp3');

  const endOfGameRound = () => {
    strokeCountdownDing.play();
    document.getElementById('stroke-counter-button').disabled = true;
  }

  const addToStrokeScore = () => {
    setStrokeScore(strokeScore + 1);
    // prints the correct number
    console.log(strokeScore)
    if (strokeCountdown === 0) {
        endOfGameRound()
    }
  }

  const subtractStrokeScore = () => {
    setStrokeScore(strokeScore - 1);
  }

  const countDown = () => {
    // let strokeCountdown = Math.floor(Math.random() * 31) + 100;
    let strokeCountdown = 10
    let strokeCountdownSpeedOptions = [1000, 500, 300, 200];
    let strokeCountDownSpeed = strokeCountdownSpeedOptions[Math.floor(Math.random()*strokeCountdownSpeedOptions.length)];
    let strokeCounter = setInterval(() => {
        strokeCountdown--
        // this is always giving me...1...?
        console.log('the score is: ' + strokeScore)
        setStrokeCountdown(strokeCountdown)
        if (strokeCountdown === 0) {
            endOfGameRound()
            clearInterval(strokeCounter)
            setTotalStrokeScore(strokeScore);
        }
    }, strokeCountDownSpeed)
  }

  useEffect(() => {
    countDown();
  }, []);

  return (
    <div className="gane__score-card">
      <div className="gane__speed-level">
          Speed: idk
      </div>
      <div className="gane__stroke-countdown">
          Countdown: {strokeCountdown}
      </div>
      <p>Score: {strokeScore}</p>
      <button id="stroke-counter-button" onClick={addToStrokeScore}>
          {strokeCountdown === 0 ? 'Game Over' : 'Stroke'}
      </button>
      {/* window.location just temp for now */}
      {strokeCountdown === 0 
        ? <button onClick={() => window.location.reload(false)}>Play Again</button>
        : <button disabled>Game in Progress</button>
      }
      <div className="gane__total-score">
          Total score: {totalStrokeScore}
      </div>
    </div>
  );
}

export default ScoreCard;

如果您看上面的示例,我会评论它给出正确数字的地方以及它似乎停滞在&q;1&q;的地方-为什么会这样?

我也尝试将其作为其他变量。

import React, { useEffect, useState } from 'react';

function ScoreCard() {

  const [strokeScore, setStrokeScore] = useState(1);

  const [totalStrokeScore, setTotalStrokeScore] = useState(1);

  const [strokeCountdown, setStrokeCountdown] = useState();

  const strokeCountdownDing = new Audio('/sounds/round-complete.mp3');

  // make new variable, maybe? 
  let strokeScoreCount = 0;

  const endOfGameRound = () => {
    strokeCountdownDing.play();
    document.getElementById('stroke-counter-button').disabled = true;
  }

  const addToStrokeScore = () => {
    setStrokeScore(strokeScore + 1);
    // prints the correct number
    console.log(strokeScore)
    // but this just gives me zero?
    strokeScoreCount = strokeScoreCount + 1;
    console.log('maybe do a different var? : ' + strokeScoreCount)
    if (strokeCountdown === 0) {
        endOfGameRound()
    }
  }

  const subtractStrokeScore = () => {
    setStrokeScore(strokeScore - 1);
  }

  const countDown = () => {
    // let strokeCountdown = Math.floor(Math.random() * 31) + 100;
    let strokeCountdown = 10
    let strokeCountdownSpeedOptions = [1000, 500, 300, 200];
    let strokeCountDownSpeed = strokeCountdownSpeedOptions[Math.floor(Math.random()*strokeCountdownSpeedOptions.length)];
    let strokeCounter = setInterval(() => {
        strokeCountdown--
        // this is always giving me...1...?
        console.log('the score is: ' + strokeScore)
        // this just gives me zero all the time? why? 
        console.log('the new variable to use is: ' + strokeScoreCount)
        setStrokeCountdown(strokeCountdown)
        if (strokeCountdown === 0) {
            endOfGameRound()
            clearInterval(strokeCounter)
            setTotalStrokeScore(strokeScore);
        }
    }, strokeCountDownSpeed)
  }

  useEffect(() => {
    countDown();
  }, []);

  return (
    <div className="game__score-card">
      <div className="game__speed-level">
          Speed: idk
      </div>
      <div className="game__stroke-countdown">
          Countdown: {strokeCountdown}
      </div>
      <p>Score: {strokeScore}</p>
      <button id="stroke-counter-button" onClick={addToStrokeScore}>
          {strokeCountdown === 0 ? 'Game Over' : 'Stroke'}
      </button>
      {/* window.location just temp for now */}
      {strokeCountdown === 0 
        ? <button onClick={() => window.location.reload(false)}>Play Again</button>
        : <button disabled>Game in Progress</button>
      }
      <div className="game__total-score">
          Total score: {totalStrokeScore}
      </div>
    </div>
  );
}

export default ScoreCard;

使用新变量只会使我始终为零,而strokeScore在该函数中仅永久停留在1。但这是一个州,你在任何地方都不能得到州吗?

如何从一个状态获取值,确保它在所有作用域中都正确,并将其传递到另一个状态?

注意:下面的答案解释了状态和范围,但代码破坏了setInterval。问题来了:useState with an argument in it's array is breaking a setInterval and makes it glitchy and erratic

推荐答案

如果执行setState(somevalue); console.log(state)state将显示旧值而不是新值,因为它尚未更新。

如果执行以下操作,strokeScore将反映旧值,因为它尚未更新。

    setStrokeScore(strokeScore + 1);
    console.log(strokeScore)

您可以在useEffect调用中看到更新后的分数。试着做以下事情,你就知道我在说什么了。

  useEffect(() => {
          console.log('Score in useeffect', strokeScore);
  }, [strokeScore])

  const addToStrokeScore = () => {
         setStrokeScore(strokeScore + 1);
         console.log('Score in function', strokeScore);
  }

此外,如果新值依赖于旧值,则设置状态的正确方法是

         setStrokeScore( prev => prev + 1);

因此最终代码应类似于以下

 useEffect(() => {
          console.log('Score in useeffect', strokeScore); //shows new value
  }, [strokeScore])

  const addToStrokeScore = () => {
         setStrokeScore(prev => prev + 1);
         console.log('Score in function', strokeScore); //shows old value
  }

甚至更好,让事情更上一层楼。

  const addToStrokeScore = () => {
         const newScore = strokeScore + 1;
         // do whatever you need with the new score, then update state when done.
         setStrokeScore(newScore);
         console.log('Score in function', newScore);
   }

这篇关于不同函数中状态变量的值不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆