Javascript 如何设置;间隔id“;表示反应
我正在尝试创建一个允许创建计时器列表的应用程序。每个计时器都可以暂停和恢复Javascript 如何设置;间隔id“;表示反应,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在尝试创建一个允许创建计时器列表的应用程序。每个计时器都可以暂停和恢复 const [time, setTime] = useState({ hours: 0, minutes: 0, seconds: 1 }); useEffect(() => { const tick = () => { const duration = moment.duration( moment.duration((moment().format('X'
const [time, setTime] = useState({ hours: 0, minutes: 0, seconds: 1 });
useEffect(() => {
const tick = () => {
const duration = moment.duration(
moment.duration((moment().format('X') - data.unix) * 1000, 'milliseconds') + 1000,
'milliseconds'
);
setTime({ hours: duration.hours(), minutes: duration.minutes(), seconds: duration.seconds() });
};
const timer = setInterval(tick, 1000);
return () => {
clearInterval(timer);
};
}, [data.unix]);
这就是我现在所拥有的,我正在尝试做一个暂停选项,我认为可以通过清除interval来停止计时器来实现。但计时器在useEffect范围内,无法访问以删除useEffect之外的内容。如果我将计时器置于setState,则会导致错误。有什么建议吗?为了在
useffect
之外保持对间隔的引用,您应该使用useRef
这将允许清除事件处理程序上的间隔,例如:onClick
const IntervalComponent = (props) => {
const intervalRef = useRef();
useEffect(() => {
intervalRef.current = getInterval();
return () => clearInterval(intervalRef.current);
}, []);
const getInterval = () => {
const startTime = new Date().getTime();
const progressInterval = setInterval(() => {
// do on each interval
}, 10);
return progressInterval;
};
const onClickHandler = (e) => clearInterval(intervalRef.current);
return <button onClick={onClickHandler}>Clear interval</button> ;
}
const IntervalComponent=(道具)=>{
const intervalRef=useRef();
useffect(()=>{
intervalRef.current=getInterval();
return()=>clearInterval(intervalRef.current);
}, []);
常量getInterval=()=>{
const startTime=new Date().getTime();
const progressInterval=setInterval(()=>{
//在每一个时间间隔做什么
}, 10);
返回间隔;
};
const onClickHandler=(e)=>clearInterval(intervalRef.current);
返回清除间隔;
}
为了在useffect
之外保持对间隔的引用,您应该使用useRef
这将允许清除事件处理程序上的间隔,例如:onClick
const IntervalComponent = (props) => {
const intervalRef = useRef();
useEffect(() => {
intervalRef.current = getInterval();
return () => clearInterval(intervalRef.current);
}, []);
const getInterval = () => {
const startTime = new Date().getTime();
const progressInterval = setInterval(() => {
// do on each interval
}, 10);
return progressInterval;
};
const onClickHandler = (e) => clearInterval(intervalRef.current);
return <button onClick={onClickHandler}>Clear interval</button> ;
}
const IntervalComponent=(道具)=>{
const intervalRef=useRef();
useffect(()=>{
intervalRef.current=getInterval();
return()=>clearInterval(intervalRef.current);
}, []);
常量getInterval=()=>{
const startTime=new Date().getTime();
const progressInterval=setInterval(()=>{
//在每一个时间间隔做什么
}, 10);
返回间隔;
};
const onClickHandler=(e)=>clearInterval(intervalRef.current);
返回清除间隔;
}
我制作了这种工作示例(使用RN,但逻辑保持不变)。我嘲笑了时刻库的功能:
正如在已经投票的答案中所解释的,在使用useffect
和间隔时,需要使用useRef
核心功能:
const App = () => {
let timer = useRef();
const [time, setTime] = useState({ hours: 0, minutes: 0, seconds: 1 });
const [toggleLabel, setToggleLabel] = useState('Pause');
const tick = useCallback(() => {
// mock:
const duration = {
hours: () => '0'.padStart(2, '0'),
minutes: () => '0'.padStart(2, '0'),
seconds: () => (''+ Math.floor(Math.random() * 60)).padStart(2, '0'),
};
setTime({
hours: duration.hours(),
minutes: duration.minutes(),
seconds: duration.seconds(),
});
}, []);
const startTicking = () => setInterval(tick, 1e3);
const stopTicking = () => clearInterval(timer.current);
const toggleTimer = () => {
const shouldPause = (toggleLabel === 'Pause');
timer.current = shouldPause ? stopTicking() : startTicking();
setToggleLabel(shouldPause ? 'Resume' : 'Pause');
};
useEffect(() => {
timer.current = startTicking();
return () => {
stopTicking();
};
}, [tick]);
const { hours, minutes, seconds} = time;
return (
<View style={styles.container}>
<Text>{`${hours}:${minutes}:${seconds}`}</Text>
<TouchableOpacity style={styles.toggleButton} onPress={toggleTimer}><Text>{toggleLabel}</Text></TouchableOpacity>
</View>
);
};
const-App=()=>{
让timer=useRef();
const[time,setTime]=useState({hours:0,minutes:0,seconds:1});
常量[toggleLabel,setToggleLabel]=useState('Pause');
const tick=useCallback(()=>{
//模拟:
常数持续时间={
小时数:()=>“0”。padStart(2,“0”),
分钟数:()=>“0”。padStart(2,“0”),
秒:()=>(''+Math.floor(Math.random()*60)).padStart(2,'0'),
};
设定时间({
小时数:持续时间。小时数(),
分钟:持续时间。分钟(),
秒:持续时间。秒(),
});
}, []);
常量starttick=()=>setInterval(勾号,1e3);
const stopTicking=()=>clearInterval(timer.current);
常量切换计时器=()=>{
const shouldPause=(toggleLabel=='Pause');
timer.current=shouldPause?stoppticking():startTicking();
setToggleLabel(应暂停?'Resume':'Pause');
};
useffect(()=>{
timer.current=startTicking();
return()=>{
停止滴答声();
};
},[勾选];
常数{小时,分钟,秒}=时间;
返回(
{${hours}:${minutes}:${seconds}}}
{切换标签}
);
};
我制作了这种工作示例(使用RN,但逻辑保持不变)。我嘲笑了时刻库的功能:
正如在已经投票的答案中所解释的,在使用useffect
和间隔时,需要使用useRef
核心功能:
const App = () => {
let timer = useRef();
const [time, setTime] = useState({ hours: 0, minutes: 0, seconds: 1 });
const [toggleLabel, setToggleLabel] = useState('Pause');
const tick = useCallback(() => {
// mock:
const duration = {
hours: () => '0'.padStart(2, '0'),
minutes: () => '0'.padStart(2, '0'),
seconds: () => (''+ Math.floor(Math.random() * 60)).padStart(2, '0'),
};
setTime({
hours: duration.hours(),
minutes: duration.minutes(),
seconds: duration.seconds(),
});
}, []);
const startTicking = () => setInterval(tick, 1e3);
const stopTicking = () => clearInterval(timer.current);
const toggleTimer = () => {
const shouldPause = (toggleLabel === 'Pause');
timer.current = shouldPause ? stopTicking() : startTicking();
setToggleLabel(shouldPause ? 'Resume' : 'Pause');
};
useEffect(() => {
timer.current = startTicking();
return () => {
stopTicking();
};
}, [tick]);
const { hours, minutes, seconds} = time;
return (
<View style={styles.container}>
<Text>{`${hours}:${minutes}:${seconds}`}</Text>
<TouchableOpacity style={styles.toggleButton} onPress={toggleTimer}><Text>{toggleLabel}</Text></TouchableOpacity>
</View>
);
};
const-App=()=>{
让timer=useRef();
const[time,setTime]=useState({hours:0,minutes:0,seconds:1});
常量[toggleLabel,setToggleLabel]=useState('Pause');
const tick=useCallback(()=>{
//模拟:
常数持续时间={
小时数:()=>“0”。padStart(2,“0”),
分钟数:()=>“0”。padStart(2,“0”),
秒:()=>(''+Math.floor(Math.random()*60)).padStart(2,'0'),
};
设定时间({
小时数:持续时间。小时数(),
分钟:持续时间。分钟(),
秒:持续时间。秒(),
});
}, []);
常量starttick=()=>setInterval(勾号,1e3);
const stopTicking=()=>clearInterval(timer.current);
常量切换计时器=()=>{
const shouldPause=(toggleLabel=='Pause');
timer.current=shouldPause?stoppticking():startTicking();
setToggleLabel(应暂停?'Resume':'Pause');
};
useffect(()=>{
timer.current=startTicking();
return()=>{
停止滴答声();
};
},[勾选];
常数{小时,分钟,秒}=时间;
返回(
{${hours}:${minutes}:${seconds}}}
{切换标签}
);
};