Javascript clearInterval不是清除间隔
我知道这个问题已经被问了很多次了。。。但是我认为我做的一切都是正确的,它仍然不工作,clearInterval没有停止间隔,函数仍然每1秒被调用一次 这是我的全部代码:Javascript clearInterval不是清除间隔,javascript,reactjs,Javascript,Reactjs,我知道这个问题已经被问了很多次了。。。但是我认为我做的一切都是正确的,它仍然不工作,clearInterval没有停止间隔,函数仍然每1秒被调用一次 这是我的全部代码: const [playerState, setPlayerState] = useState({ playing: true }); let [duration, setDuration] = useState(0); let counter = null; let count = () => {
const [playerState, setPlayerState] = useState({ playing: true });
let [duration, setDuration] = useState(0);
let counter = null;
let count = () => {
setDuration(++duration);
};
let handlePlay = () => {
setPlayerState({ playing: true });
counter = setInterval(count, 1000); //call count every 1 second, working fine
console.log("playing");
console.log(duration);
};
let handlePause = () => {
setPlayerState({ playing: false });
clearInterval(counter); // doesn't work the function is still being called every 1 second.
console.log("paused");
console.log(duration);
};
在调用handleplay时,持续时间应每1秒增加1,这很好,调用handlePause后,持续时间应停止增加,但不是这样!
感谢您回答当调用
handlePlay
时,它会调用setPlayerState
。这会触发一个重新渲染器,从而产生一个新的计数器
,其值为null
。新的handlePause
在该值周围有一个闭包。您可以尝试将计数器分配给state/ref。问题是,每次调用组件函数来呈现组件(在任何一系列状态更改之后),都会创建一个新的计数器
局部变量。存储计时器句柄的那个已不存在。您必须将计时器句柄保存在以后可以使用的地方(基本上是state或ref)。您还需要确保在组件卸载时有一个清除回调来取消计时器
见评论:
const [playerState, setPlayerState] = useState({ playing: true });
let [duration, setDuration] = useState(0);
// A ref to hold the timer handle
const timerRef = useRef(0);
// Register an unmount callback
useEffect(() => {
// The return value is the clean up callback
return () => {
clearInterval(timerRef.current);
};
}, []); // <== Empty dependency array means callback is called on unmount only
let count = () => {
setDuration(++duration);
};
let handlePlay = () => {
setPlayerState({ playing: true });
// *** Use the ref
clearInterval(timerRef.current);
timerRef.current = setInterval(count, 1000); //call count every 1 second, working fine
console.log("playing");
console.log(duration);
};
let handlePause = () => {
setPlayerState({ playing: false });
// *** Use the ref
clearInterval(timerRef.current);
timerRef.current = 0;
console.log("paused");
console.log(duration);
};
const[playerState,setPlayerState]=useState({playing:true});
let[duration,setDuration]=useState(0);
//用于固定计时器手柄的ref
常数timerRef=useRef(0);
//注册一个卸载回调
useffect(()=>{
//返回值是清除回调
return()=>{
clearInterval(timerRef.current);
};
}, []); // {
设置持续时间(++持续时间);
};
让handlePlay=()=>{
setPlayerState({playing:true});
//***使用ref
clearInterval(timerRef.current);
timerRef.current=setInterval(count,1000);//每1秒调用一次,工作正常
控制台日志(“播放”);
console.log(持续时间);
};
让handlePause=()=>{
setPlayerState({playing:false});
//***使用ref
clearInterval(timerRef.current);
timerRef.current=0;
控制台日志(“暂停”);
console.log(持续时间);
};
是的,这很有道理,我是新手,不知道useRef是如何工作的,我想我应该学习一下,谢谢。