React - 以秒为单位获取长按按钮的时间

React - get time of long pressing button in seconds

我正在尝试 return 按住按钮的秒数。

例如:“点击+按住,初始化 -> 计数并显示 1、2、3、4、5 -> 离开按钮 -> 重置回 0”

我已经接近了。它在我的控制台中运行良好,但每当我尝试更新状态时,它都会陷入无限循环。

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

const Emergency = () => {
  let counter = 0;
  let timerinterval;

  const [ms, setMs] = useState(counter);

  const timer = start => {
    console.log("tick tock");
    console.log(start);
    if (start === true && counter >= 1) {
      timerinterval = setInterval(() => {
        counter += 1;
        console.log(counter);
        setMs(counter); //When I remove this, the infinite loop disappears.
      }, [1000]);
    } else {
      setMs(0);
    }
  };

  const pressingDown = e => {
    console.log("start");
    e.preventDefault();
    counter = 1;
    timer(true);
  };

  const notPressingDown = e => {
    console.log("stop");
    e.preventDefault();
    timer(false);
    setMs(0);
    clearInterval(timerinterval);
  };

  return (
    <>
      <button
        onMouseDown={pressingDown}
        onMouseUp={notPressingDown}
        onTouchStart={pressingDown}
        onTouchEnd={notPressingDown}
        className="button is-primary mt-3"
      >
        Emergency
      </button>
      <br />
      Time holding it is.... {ms}
    </>
  );
};

export default Emergency;


一个简单的方法是计算 mouseDown 和 mouseUp 之间的时间差,但为了用户体验,我想在按住按钮时 {ms} 实时更新。

有什么建议吗?

谢谢!

您的代码有两个问题:

  • 您没有清除间隔。 timeInterval 是一个新变量,每当您的组件被重新渲染时。您需要使用 ref (const timeInterval = React.useRef(null); ... timeInterval.current = ... ; clearInterval(timeInterval.current);
  • 您还需要从 pressingDowm 函数中删除 counter = 1;,因为在每个 setMs 之前,您要将它递增一个
const Emergency = () => {
  let counter = 0;
  let timerinterval = React.useRef((null as unknown) as any);

  const [ms, setMs] = React.useState(counter);

  const timer = (start: any) => {
    console.log('tick tock');
    console.log(start);
    if (start === true && counter >= 1) {
      timerinterval.current = setInterval(() => {
        console.log(counter);
        setMs(counter); //When I remove this, the infinite loop disappears.
        counter += 1;
        //@ts-ignore
      }, [1000]);
    } else {
      setMs(0);
    }
  };

  const pressingDown = (e: any) => {
    console.log('start');
    e.preventDefault();
    counter = 1;
    timer(true);
  };

  const notPressingDown = (e: any) => {
    console.log('stop');
    e.preventDefault();
    timer(false);
    setMs(0);
    clearInterval(timerinterval.current);
  };

  return (
    <>
      <button
        onMouseDown={pressingDown}
        onMouseUp={notPressingDown}
        onTouchStart={pressingDown}
        onTouchEnd={notPressingDown}
        className="button is-primary mt-3"
      >
        Emergency
      </button>
      <br />
      Time holding it is.... {ms}
    </>
  );
};

这是经过编辑的代码(带有一些 TypeScript 内容,对此深感抱歉)