我已经创建了一个叫做Timer的功能组件。我想运行一个3秒的计时器,然后运行一个6秒的计时器。然而,第二个定时器一开始就停止了。
我认为问题在于,第二个定时器正在使用来自第一个定时器的状态值。我不知道为什么会这样。我假设第二个定时器是一个新实例,所以它不应该与第一个计时器有任何链接。
这是我的密码:
import React, { useEffect, useState } from 'react';
function App() {
const [timer1Up, setTimer1Up] = useState(false);
const [timer2Up, setTimer2Up] = useState(false);
if(!timer1Up) {
return <Timer duration={3} setTimeUp={setTimer1Up}/>
}
if(timer1Up && !timer2Up) {
return <Timer duration={6} setTimeUp={setTimer2Up}/>
}
if(timer1Up && timer2Up) {
return <>Out of all your time buddy!!</>
}
return <>I have no purpose</>;
}
interface TimerProps {
duration: number;
setTimeUp: any;
}
const Timer = (props: TimerProps) => {
const [timeLeft, setTimeLeft] = useState(props.duration);
useEffect(() => {
setTimeout(() => {
setTimeLeft(timeLeft - 1);
}, 1000);
if(timeLeft === 0) {
props.setTimeUp(true);
}
});
return <>{timeLeft} s</>
}
export default App;
发布于 2021-05-22 13:00:47
if(!timer1Up) {
return <Timer duration={3} setTimeUp={setTimer1Up}/>
}
if(timer1Up && !timer2Up) {
return <Timer duration={6} setTimeUp={setTimer2Up}/>
}
react使用的主要方式是根据组件的类型判断它是需要挂载新组件还是重用现有组件。第一次呈现时,您将返回一个<Timer>
,因此react将挂载一个新的计时器组件,然后开始进行倒计时。一旦完成了第一个倒计时,您将再次呈现,也会返回一个<Timer>
。因此,据反应所知,唯一改变的是定时器上的道具。React保持相同的组件安装,具有相同的状态。
因此有两个选择: 1)强迫它重新安装;2)如果它的道具改变,让计时器重置。
为了迫使它重新装入,您需要使用键来明确地反应这些是不同的元素。这样,它将卸载旧计时器并装入一个新计时器,而新计时器可以有自己的状态来计数。
if(!timer1Up) {
return <Timer key="first" duration={3} setTimeUp={setTimer1Up}/>
}
if(timer1Up && !timer2Up) {
return <Timer key="second" duration={6} setTimeUp={setTimer2Up}/>
}
要使它与改变道具一起工作,您需要添加逻辑来重置倒计时。您必须决定应该重置倒计时的条件,但有一个选项是,无论何时持续时间发生变化,您都可以重新开始:
const Timer = (props: TimerProps) => {
const [timeLeft, setTimeLeft] = useState(props.duration);
useEffect(() => {
setTimeLeft(props.duration);
const intervalId = setInterval(() => {
setTimeLeft(prev => {
const next = prev -1;
if (next === 0) {
clearInterval(intervalId);
// Need to slightly delay calling props.setTimeUp, because setting
// state in a different component while in the middle of setting
// state here can cause an error
setTimeout(() => props.setTimeUp(true));
}
return next;
});
}, 1000);
return () => { clearInterval(intervalId); }
}, [props.duration]); // <---- dependency array to reset when the duration changes
return <>{timeLeft} s</>
}
有关react如何决定挂载/卸载组件的更多信息,请参见这一页是关于和解的。
https://stackoverflow.com/questions/67649614
复制相似问题