【问题标题】:How to break a loop onClick ReactJS如何打破 onClick ReactJS 的循环
【发布时间】:2020-12-28 13:51:22
【问题描述】:

我有一个使用async await() 做一些动画的函数。 我想播放/暂停动画onClick。我使用useState 来更新变量,但函数的行为不符合我的要求。 const print () 正在运行并且当我单击按钮时,文本会更新,但该功能不会中断。在日志中,“play”被打印了 100 次。我猜useStateasync 造成了一些问题。我该如何解决这个问题?

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>
    )
}

【问题讨论】:

    标签: javascript reactjs asynchronous async-await


    【解决方案1】:

    ButtonText 被声明为 const - 它不能在函数组件的给定调用中更改其值。

    如果没有更多信息,我会使用 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;
    }
    

    另一种方法是将被迭代的索引放入状态,而不是循环 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);
      }
    };
    

    要停止它,请致电setPrintI(0)

    【讨论】:

    • 我正在尝试第一种方法 buttonTextRef,变量没有在循环内更新。我在等待检查后打印console.log(buttonTextRef.current+ " " +ButtonText ); ,每次打印play play 。我尝试了var 而不是const,但仍然无法正常工作。
    • 您确定您在答案中使用了useEffect 吗?如果实施得当,它将更新参考。
    • 我认为我使用得当。因为我使用的是await,所以我必须将函数声明为const print= async () =&gt;,这就是我额外添加的所有内容。在 SetButtonText 函数中,ButtonTextbuttonTextRef 都在正确更新。
    • 您能否将实时 sn-p 编辑到说明问题的问题中,或者链接到代码框或其他内容? buttonTextRef.current = ButtonText; 真的应该 每次ButtonText 更新时都正确更新 ref,听起来好像还有其他事情发生
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 2015-10-04
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多