我正在react.js中制作一个倒计时计时器脚本。在计时器启动之前,会显示3或5秒的倒计时,两个倒计时的数据都来自另一个组件。我正在尝试用按钮停止/暂停主倒计时。我的问题是如何控制由useEffect((执行的函数中的数据?我正在尝试为btn创建一个状态,但该状态的范围是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;```
创建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>
);
}
您可以使用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范围中获得计时器
return (
...
<button type="button" className="btn btn-stop" onClick={()=>{clearInterval(countRef.current)}}>Pause Button</button>
...
)