如何在react with hook中通过toggle函数设置和清除间隔



我正在尝试构建一个计时器,它由一个带有handleToggle功能的按钮触发,看起来像:

const handleToggle = () => {
let timer = () => setInterval(() => {
dispatch({ type: "COUNT", payload: Date.now() - startTime });
}, 100);
const startTime = Date.now() - AppState.runningTime;
if (AppState.countingStarted) {
dispatch({
type: "COUNTING_STARTED",
payload: false
});
clearInterval(timer());
} else {
timer()
dispatch({ type: "COUNTING_STARTED", payload: true });
}
};

COUNTING_STARTED是一个调度函数,用于切换AppState.countingStarted.

我正在努力停止计时器,如何清除计时器间隔?我试过了:

const handleToggle = () => {
let timer;
if (AppState.countingStarted) {
dispatch({
type: "COUNTING_STARTED",
payload: false
});
clearInterval(timer);
} else {
timer = setInterval(() => {
dispatch({ type: "COUNT", payload: Date.now() - startTime });
}, 100);
const startTime = Date.now() - AppState.runningTime;
dispatch({ type: "COUNTING_STARTED", payload: true });
}
};

但没有区别。。。

在您的示例中,对intervalId的引用在函数执行结束时丢失。

您应该使用实例变量来存储intervalId。如果您有Class组件,您可以使用以下代码:

handleToggle = () => {
// clear the interval, no matter the value of AppState.countingStarted
// this prevent from recreating the interval multiple times
clearInterval(this.timerId);
if (AppState.countingStarted) {
dispatch({type: "COUNTING_STARTED",payload: false});   
} else {
// store the timer id in an instance variable
this.timerId = setInterval(() => {
dispatch({ type: "COUNT", payload: Date.now() - startTime });
}, 100);
dispatch({ type: "COUNTING_STARTED", payload: true });
}

如果您在Function组件中,您可以使用钩子useRef来获得相同的行为:

const timerIdRef = useRef(null);
const handleToggle = () => {
clearInterval(timerIdRef.current);
if (AppState.countingStarted) {
dispatch({type: "COUNTING_STARTED",payload: false});   
} else {
// store the interval id into the current property
timerIdRef.current = setInterval(() => {
dispatch({ type: "COUNT", payload: Date.now() - startTime });
}, 100);
dispatch({ type: "COUNTING_STARTED", payload: true });
}

有几件事:传递给clearInterval的必须是setInterval的返回值;在第一个例子中,你将自己的函数传递给它。第二个例子有这个权利,但你将timer(调用setInterval的结果(存储在toggle函数的范围内,这意味着一旦函数完成,你就失去了对它的引用;下次调用函数(例如停止它(时,您将重新定义timer,这不是您想要的。

您所需要的只是将timer变量保持在它将持久存在的范围内。例如:

let timer = null;
const handleToggle = () => {
if (AppState.countingStarted) {
dispatch({
type: "COUNTING_STARTED",
payload: false
});
clearInterval(timer);
} else {
timer = setInterval(() => {
dispatch({ type: "COUNT", payload: Date.now() - startTime });
}, 100);
const startTime = Date.now() - AppState.runningTime;
dispatch({ type: "COUNTING_STARTED", payload: true });
}
};

此函数可以多次调用;CCD_ 10变量将始终存在。

相关内容

  • 没有找到相关文章

最新更新