[英]SetInterval Keeps Running forever and doesnt stop
我已经被这个问题困住了很长一段时间。 我正在制作一个矩阵风格的主题博客,当我的商店中的 displayMatrix 雨 state 变为 true 时,在后台显示矩阵雨效果,当 displayMatrix 变为 false 时停止显示矩阵雨效果。 我需要使用 setInterval 来绘制矩阵雨效果,在 setInterval 内部我称之为“绘制”function,它内部有一个循环,使用 canvas 工具在背景中绘制矩阵雨字符。 我遇到的问题是,当我将 displayMatrix state 更改为 true,而不是稍后更改为 false 时,循环继续运行,我从未在控制台日志中看到 'id being clear is => #' 即使我有将 displayMatrix state 更改为 false。 我试图在以下沙箱中模仿我的代码的准系统,以便您可以看到代码https://playcode.io/933189/的整体结构。 我正在使用 reacts 内置的 useReducer/useContext 挂钩代替 redux。 我注意到的另一个奇怪的事情是,在代码沙箱中,当我将 displayMatrix state 更改为 true,然后将其变为 false,它至少会停止控制台中的“运行矩阵雨绘图代码”,但在我的原始代码中在 VisualStudio Code 上,我一直在控制台中看到“运行矩阵雨绘图代码”,它基本上永远运行,直到它用完 memory
import React from 'react';
import {useEffect, useContext, useState} from 'react';
import {GlobalStore} from '../Store.jsx';
export function App(props) {
const [state, dispatch] = useContext(GlobalStore);
const [intervalId, setIntervalId] = useState(0);
useEffect(() => {
const draw = () => {
// pretend 100 is the width of the screen
for (let i = 0; i < 100; i += 1)
{
console.log("run matrix rain drawing code");
}
}
// if we want to diplay the matrix rain
if (state.displayMatrix) {
// only create an interval when interval does
// not already exist
if (intervalId === 0) {
const id = setInterval(draw, 90);
console.log("id being set is => " + id);
setIntervalId(id);
}
else {
console.log("id being cleared is => " + intervalId);
clearInterval(intervalId);
setIntervalId(0);
}
}
// if we want to stop matrix rain
else {
console.log("id being cleared is => " + intervalId);
clearInterval(intervalId);
setIntervalId(0);
}
}, [state.displayMatrix])
return (
<div>
<div onClick={() => dispatch({type: 'CHANGE_MATRIX_RAIN_BACKGROUND_DISPLAY_STATE'})}>Matrix Display {state.displayMatrix ? 'Off' : 'On'}</div>
</div>
)
}
我有这个时间Counter helper class
import { setIntervalAsync, clearIntervalAsync, SetIntervalAsyncTimer } from 'set-interval-async/fixed';
export class TimeCounter {
private interval: SetIntervalAsyncTimer | undefined;
private onRepeat: () => any;
private onStop: () => any;
constructor(onRepeat: () => any, onStop: () => any) {
this.onRepeat = onRepeat;
this.onStop = onStop;
}
startCounter(milliseconds: number) {
if (!this.isActive()) {
this.interval = setIntervalAsync(async () => {
this.onRepeat();
}, milliseconds);
}
}
stopCounter(): void {
if (this.interval !== undefined) {
this.onStop();
clearIntervalAsync(this.interval);
this.interval = undefined;
}
}
isActive(): boolean {
return this.interval !== undefined;
}
}
用法:
export function useCounter() {
const counter = new TimeCounter(onRepeatCounter, () => null);
const [result, setResult] = useState(0);
useEffect(() => {
if (!counter.isActive() && defaultDate === undefined) {
counter.startCounter(1000);
}
return () => counter.stopCounter();
});
function onRepeatCounter() {
// Custom functionality
setResult((val) => val + 1);
}
return result;
}
playcode 似乎工作正常,只需按 Show More 即可查看日志结束。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.