简体   繁体   English

如何打破循环 onClick ReactJS

[英]How to break a loop onClick ReactJS

I have a function that does some animation using async await() .我有一个 function 使用async await()做了一些 animation 。 I want to play/pause the animation onClick .我想播放/暂停 animation onClick I used useState to update the variable but the function is not behaving as I want.我使用useState来更新变量,但 function 的行为不像我想要的那样。 While the const print () is running and when I click on the button, text updates, but the function doesn't break.虽然const print ()正在运行并且当我单击按钮时,文本会更新,但 function 不会中断。 In the log, "play" is printed 100 times.在日志中,“play”被打印了 100 次。 I'm guessing useState and async is causing something.我猜是useStateasync导致了一些事情。 How can I solve this?我该如何解决这个问题?

const Test= props => {

    const [ButtonText, SetButtonText] = useState("Play");
    const ToggleButtonText = () => {
        if(ButtonText == "Play")          
            SetButtonText("Pause")

        if(ButtonText == "Pause")
            SetButtonText("Play")
    }

    const delay = ms => new Promise(res => setTimeout(res, ms));

    const print= () => {
        for(var i = 0; i < 100; i++)        
        {
            ///
               work
               await delay(1000);
               work
            ///
           console.log(ButtonText);
           
           if(ButtonText == "Pause")
               break ; 

        }
    };
    return (
           <div>
              <div>
                   ///work component///
              </div>
            <button onClick = {() => ToggleButtonText()}> {ButtonText}</button>
           </div>
    )
}

The ButtonText is declared as const - it can't change its value inside a given call of the functional component. ButtonText被声明为const - 它不能在功能组件的给定调用中更改其值。

Without more info, I'd use a ref as well as state, so that the loop can see if the ref gets changed:如果没有更多信息,我将使用 ref 以及 state,以便循环可以查看 ref 是否已更改:

const buttonTextRef = useRef();
// Update the ref to ButtonText every time ButtonText changes:
useEffect(() => {
  buttonTextRef.current = ButtonText;
}, [ButtonText]);
if (buttonTextRef.current === 'Pause') {
  break;
}

Another method would be to put the index being iterated over into state, and instead of looping 100 times, re-render 100 times, eg, something along the lines of:另一种方法是将要迭代的索引放入 state 中,而不是循环 100 次,而是重新渲染 100 次,例如,类似于以下内容:

const [printI, setPrintI] = useState(0);
if (printI) {
  // Then we're in the middle of iterating
  // work
  if (printI < 100) {
    setTimeout(() => {
      setPrintI(printI + 1);
    }, 1000);
  } else {
    setPrintI(0);
  }
};

and to stop it, call setPrintI(0) .并停止它,调用setPrintI(0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM