ReactJS + Typescript中的条件setInterval和clearInterval

时间:2020-05-06 09:04:01

标签: javascript reactjs typescript setinterval clearinterval

在单页Web应用程序中,城市的地图带有交通图层。
目前,正在使用实时模式开关,如果该模式处于打开状态,则应该每5分钟更新一次地图上的路况图层。
关闭实时模式后,5分钟计时器应关闭。

对于此要求,很少有博客和帖子提供了两个选项的提示。
1. Javascript方法:setInterval和clearInterval
2.使用网络套接字

由于该Web应用程序除缺乏Web套接字知识外仅拥有几个用户,因此决定选择第一个选项。 但是,当开关转到关闭模式时,成功执行clearInterval()会遇到困难。
在下面的代码中,传递给clearInterval的'timeout'值始终是不确定的。

    private void MockHttpContextGetToken(
        Mock<IHttpContextAccessor> httpContextAccessorMock,
        string tokenName, string tokenValue, string scheme = null)
    {
        var authenticationServiceMock = new Mock<IAuthenticationService>();
        httpContextAccessorMock
            .Setup(x => x.HttpContext.RequestServices.GetService(typeof(IAuthenticationService)))
            .Returns(authenticationServiceMock.Object);

        var authResult = AuthenticateResult.Success(
            new AuthenticationTicket(new ClaimsPrincipal(), scheme));

        authResult.Properties.StoreTokens(new[]
        {
            new AuthenticationToken { Name = tokenName, Value = tokenValue }
        });

        authenticationServiceMock
            .Setup(x => x.AuthenticateAsync(httpContextAccessorMock.Object.HttpContext, scheme))
            .ReturnsAsync(authResult);
    }

看起来好像有条件地执行setInterval,而clearInterval不是一个选择。
十年后开始从事javascript开发,我想念什么?
关于替代方法的任何建议都将适用。
使用ReactJS v16.11,Typescript v3.7

1 个答案:

答案 0 :(得分:1)

这里的问题是timeout变量是在handleOkBtnClick中定义的,因此无论何时调用此函数,超时值都会重置为undefined,如果live为true,则将其设置为timerId

这里的解决方案是将计时器移至类变量

class TrafficLights extends React.Component {
   timeout = null
   ...
   handleOkBtnClick = (): void => {
    if(live){
          this.timeout = setInterval(updateFilter, 60000);
          console.log('live ON == '+ this.timeout); // prints number like 89 or 146
        }else{
          console.log('live Off == '+ this.timeout); 
          clearInterval(this.timeout);           
        }
     }
   }
   ...
}

现在看来您正在使用功能组件,因此如果您使用react-hooks,则可以将超时存储在useRef

const TrafficLights = () =>   {
   const timeout = useRef<number | null>(null);
    ...
     const handleOkBtnClick = (): void => {
        if(live){
              timeout.current = window.setInterval(updateFilter, 60000);
              console.log('live ON == '+ timeout.current); // prints number like 89 or 146
            }else{
              console.log('live Off == '+ timeout.current); 
              clearInterval(timeout.current);           
            }
         }
       }
      ...
  }