React:ClearInterval 并立即重新开始
React: ClearInterval and Immediately Start Again
我有一个组件可以触发一个计时器,该计时器每 30 秒更新一次并发出一个 axios
请求。它使用 useRef
设置为每 30 秒更新一次函数 handleStart
被触发。
const countRef = useRef(null);
const lastUpdatedRef = useRef(null);
const [lastUpdated, setLastUpdated] = useState(Date.now())
const handleStart = () => {
countRef.current = setInterval(() => {
setTimer((timer) => timer + 1);
}, 1000);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
现在我有一个 useEffect
每当 lastUpdated
作为依赖被触发时每 30 秒运行一个 calculate
函数:
const firstCalculate = useRef(true);
useEffect(() => {
if (firstCalculate.current) {
firstCalculate.current = false;
return;
}
console.log("calculating");
calculateModel();
}, [lastUpdated]);
这会根据 lastUpdatedRef
每 30 秒更新一次 calculate
函数(00:30、01:00、01:30 等)。但是,我希望计时器从 lastUpdated
状态在其他地方被修改时重新启动(例如,如果 lastUpdated
在 00:08 被修改,下一次更新将是 00:38,01:08、01:38 等)。有办法吗?
基本上听起来您只需要另一个处理程序来清除并重新启动更新 lastUpdated
状态的 30 秒间隔。
示例:
const handleOther = () => {
clearInterval(lastUpdatedRef.current);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
}
完整示例:
const calculateModel = () => console.log("calculateModel");
export default function App() {
const countRef = React.useRef(null);
const lastUpdatedRef = React.useRef(null);
const [lastUpdated, setLastUpdated] = React.useState(Date.now());
const [timer, setTimer] = React.useState(0);
const handleStart = () => {
countRef.current = setInterval(() => {
setTimer((timer) => timer + 1);
}, 1000);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
const handleOther = () => {
clearInterval(lastUpdatedRef.current);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
const firstCalculate = React.useRef(true);
React.useEffect(() => {
if (firstCalculate.current) {
firstCalculate.current = false;
return;
}
console.log("calculating");
calculateModel();
}, [lastUpdated]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>Timer: {timer}</div>
<button type="button" onClick={handleStart}>
Start
</button>
<button type="button" onClick={handleOther}>
Other
</button>
</div>
);
}
不要忘记在卸载组件时清除任何 运行 间隔!
React.useEffect(() => {
return () => {
clearInterval(countRef.current);
clearInterval(lastUpdatedRef.current);
};
}, []);
我有一个组件可以触发一个计时器,该计时器每 30 秒更新一次并发出一个 axios
请求。它使用 useRef
设置为每 30 秒更新一次函数 handleStart
被触发。
const countRef = useRef(null);
const lastUpdatedRef = useRef(null);
const [lastUpdated, setLastUpdated] = useState(Date.now())
const handleStart = () => {
countRef.current = setInterval(() => {
setTimer((timer) => timer + 1);
}, 1000);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
现在我有一个 useEffect
每当 lastUpdated
作为依赖被触发时每 30 秒运行一个 calculate
函数:
const firstCalculate = useRef(true);
useEffect(() => {
if (firstCalculate.current) {
firstCalculate.current = false;
return;
}
console.log("calculating");
calculateModel();
}, [lastUpdated]);
这会根据 lastUpdatedRef
每 30 秒更新一次 calculate
函数(00:30、01:00、01:30 等)。但是,我希望计时器从 lastUpdated
状态在其他地方被修改时重新启动(例如,如果 lastUpdated
在 00:08 被修改,下一次更新将是 00:38,01:08、01:38 等)。有办法吗?
基本上听起来您只需要另一个处理程序来清除并重新启动更新 lastUpdated
状态的 30 秒间隔。
示例:
const handleOther = () => {
clearInterval(lastUpdatedRef.current);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
}
完整示例:
const calculateModel = () => console.log("calculateModel");
export default function App() {
const countRef = React.useRef(null);
const lastUpdatedRef = React.useRef(null);
const [lastUpdated, setLastUpdated] = React.useState(Date.now());
const [timer, setTimer] = React.useState(0);
const handleStart = () => {
countRef.current = setInterval(() => {
setTimer((timer) => timer + 1);
}, 1000);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
const handleOther = () => {
clearInterval(lastUpdatedRef.current);
lastUpdatedRef.current = setInterval(() => {
setLastUpdated(Date.now());
}, 30000);
};
const firstCalculate = React.useRef(true);
React.useEffect(() => {
if (firstCalculate.current) {
firstCalculate.current = false;
return;
}
console.log("calculating");
calculateModel();
}, [lastUpdated]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>Timer: {timer}</div>
<button type="button" onClick={handleStart}>
Start
</button>
<button type="button" onClick={handleOther}>
Other
</button>
</div>
);
}
不要忘记在卸载组件时清除任何 运行 间隔!
React.useEffect(() => {
return () => {
clearInterval(countRef.current);
clearInterval(lastUpdatedRef.current);
};
}, []);