Javascript 在React中按顺序运行两个倒计时。第二个被跳过
我已经创建了一个名为Timer的功能组件。我想先运行计时器3秒钟,然后再运行计时器6秒钟。但是,第二个计时器一启动就停止 我认为问题在于,第二个计时器正在使用第一个计时器的状态值。我不知道为什么会这样。我假设第二个计时器是一个新实例,因此它不应该与第一个计时器有任何链接 这是我的密码:Javascript 在React中按顺序运行两个倒计时。第二个被跳过,javascript,reactjs,Javascript,Reactjs,我已经创建了一个名为Timer的功能组件。我想先运行计时器3秒钟,然后再运行计时器6秒钟。但是,第二个计时器一启动就停止 我认为问题在于,第二个计时器正在使用第一个计时器的状态值。我不知道为什么会这样。我假设第二个计时器是一个新实例,因此它不应该与第一个计时器有任何链接 这是我的密码: import React, { useEffect, useState } from 'react'; function App() { const [timer1Up, setTimer1Up]
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;
react用于判断是否需要装载新组件或重用现有组件的主要方法是根据组件的类型。第一次渲染时,返回一个,因此react装载一个新的计时器组件,然后开始倒计时。第一次倒计时完成后,再次渲染,并返回一个。据react所知,唯一改变的是计时器上的道具。React以相同的状态安装相同的组件
所以有两种选择:一是强制重新安装,二是在道具改变时让计时器复位
要强制它重新装载,您需要使用键来明确这些元素是不同的。这样,它将卸载旧计时器并装载新计时器,新计时器可以有自己的倒计时状态
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决定如何装载/卸载组件的更多信息,请参阅
react用于判断是否需要装载新组件或重用现有组件的主要方法是根据组件的类型。第一次渲染时,返回一个,因此react装载一个新的计时器组件,然后开始倒计时。第一次倒计时完成后,再次渲染,并返回一个。据react所知,唯一改变的是计时器上的道具。React以相同的状态安装相同的组件
所以有两种选择:一是强制重新安装,二是在道具改变时让计时器复位
要强制它重新装载,您需要使用键来明确这些元素是不同的。这样,它将卸载旧计时器并装载新计时器,新计时器可以有自己的倒计时状态
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决定如何装载/卸载组件的更多信息,请参阅