[英]How can I Pause/Stop and Interval on a function that is executed with useEffect()?
我正在 react.js 中制作倒數計時器腳本。 在計時器開始之前,會顯示 3 或 5 秒的倒計時,這兩個倒計時的數據都來自另一個組件。 我正在嘗試使用按鈕停止/暫停主倒計時。 我的問題是如何控制由 useEffect() 執行的 function 中的數據? 我正在嘗試為 btn 創建 state,但 state 的 scope 是 useEffect
import TimerForm from './components/TimerForm';
const CountDown = (props) => {
const [timeLeft, setTimeLeft] = useState({
minutes: 0,
seconds: 0
});
const [counter, setCounter] = useState();
const [startTimer, setStartTimer] = useState(false);
const [result, setResult] = useState();
let Interval;
useEffect(() => {
let count = null;
if(startTimer){
if(counter === 0){
relog(result);
clearInterval(count);
return
}
count = setInterval(() => {
setCounter((prevcounter) => prevcounter - 1);
}, 1000);
return () => clearInterval(count);
} else {
clearInterval(count);
}
}, [startTimer, counter]);
const relog = useCallback((ForTime) => {
console.log(testing);
Interval = setInterval(() => {
setTimeLeft({
seconds: ForTime % 60,
minutes: Math.floor(ForTime / 60)% 60
});
if(ForTime === 0){
clearInterval(Interval);
return;
}
ForTime--;
},1000);
setStartTimer(false);
},[]);
const timerSettings = (data) => {
setCounter(data.counter);
setResult(data.result);
setStartTimer(true);
}
return (
<div>
<section>
<TimerForm onTimerSettings={timerSettings} />
<span>{counter}</span>
<div className="TimerClock">
<span>{timeLeft.minutes}</span><span>:</span><span>{timeLeft.seconds}</span>
</div>
<div>
<button type="button" className="btn btn-stop">Pause Button</button>
</div>
</section>
</div>
)
};
export default CountDown;```
您可以使用 useRef 存儲間隔計時器
const countRef = useRef(null);
useEffect(() => {
if (startTimer) {
if (counter === 0) {
relog(result);
clearInterval(countRef.current);
return;
}
countRef.current = setInterval(() => {
setCounter((prevcounter) => prevcounter - 1);
}, 1000);
return () => clearInterval(countRef.current);
} else {
clearInterval(countRef.current);
}
}, [startTimer, counter]);
您可以從 useEffect scope 獲取計時器
return (
...
<button type="button" className="btn btn-stop" onClick={()=>{clearInterval(countRef.current)}}>Pause Button</button>
...
)
創建一個由 useEffect() 和 useRef() 使用的 useInterval 掛鈎。
/**
*
* @param {Function} callback
* @param {number|null} delay, stopped when delay is null
*/
function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
使用useInterval
:
function App() {
const [delay, setDelay] = useState(null);
const [counter, setCounter] = useState(0);
useInterval(() => {
setCounter((counter) => counter - 1);
}, delay);
const handleChangeDelay = () => {
// stopped when delay is null
setDelay(delay === null ? 1000 : null);
};
return (
<div className="App">
<p>
<button onClick={handleChangeDelay}>trigger interval countdown</button>
</p>
<p>{counter}</p>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.