如何在鼠标按下时重复调用一个函数?

问题描述 投票:0回答:2

我使用react来构建一个需要使用我的网络摄像头的前端。我需要能够单击并按住按钮并重复调用将从相机中抓取一帧的功能。

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


export function VideoFeed(){
const[constraints] = useState({width:300,height:300})
const longPress = useLongPress(takePhoto)

let video = useRef(null)

useEffect(()=>{
    navigator.mediaDevices.getUserMedia({video:true})
    .then(stream=>{
        let vid = video.current
        vid.srcObject = stream;
        vid.play();
    })
    .catch(e=>{
        console.log(e)
    })
},[video])

function takePhoto() {
        console.log("hey")
}

return(
    <div>
        <video autoPlay ={true} ref ={video} width={constraints.width} 
            height={constraints.height}>
        </video>
        <button {...longPress}>Snap Photo</button>
    </div>
    )
}


export function useLongPress(callback=()=>{}) {
 const [startLogPress, setStartLongPress] = useState(false);

   useEffect(() => {
   let timerId;
    if (startLogPress) {
      timerId = setTimeout(callback, 0);
    } else {
      clearTimeout(timerId);
    }

return () => {
  clearTimeout(timerId);
};
 }, [startLogPress]);

    return {
      onMouseDown: () => setStartLongPress(true),
      onMouseUp: () => setStartLongPress(false),
      onMouseLeave: () => setStartLongPress(false),
      onTouchStart: () => setStartLongPress(true),
      onTouchEnd: () => setStartLongPress(false),
   };
}

我使用钩子,无法弄清楚如何循环功能。如果我在useEffect钩子中添加while循环,应用程序就会中断。单击即可,但点击并按住则不然

javascript reactjs onclick react-hooks
2个回答
2
投票

这是使用setInterval函数的工作示例。希望它适合您的具体情况。

var value = 0;
var interval;

function update() {
  value++;
  document.getElementById("value-display").innerHTML = "Value: " + value;
}

function down() {
  value = 0;
  interval = setInterval(update, 100);
}

function up() {
  clearInterval(interval);
}
<h3 id="value-display">
  Value:
</h3>

<button type="button" onmousedown="down()" onmouseup="up()">
  Click me!
</button>

1
投票

您可以使用useIntervaluseState来决定是否触发您的功能。

function useInterval(callback, delay) {
  const savedCallback = useRef();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

const onMouseDown = () => {
  console.log("mouse is down");
};

function App() {
  const [isMouseDown, setMouseDown] = useState(false);

  useInterval(onMouseDown, isMouseDown ? 100 : null);

  return (
    <div className="App">
      <h1
        onMouseDown={() => setMouseDown(true)}
        onMouseUp={() => setMouseDown(false)}
      >
        Mouse down here tp trigger the <i>onMouseDown</i> function
      </h1>
    </div>
  );
}

Run in CodeSandBox

© www.soinside.com 2019 - 2024. All rights reserved.