SetInterval on mount for a set duration
SetInterval on mount for a set duration
我在这里进行了一些问答,但无法理解我做错了什么。以下组件在控制台中打印 0
s,但未按预期更新 DOM。
const NotifPopup = ({ notif, index, closeHandler }) => {
const [timer, setTimer] = useState(0);
useEffect(() => {
const timerRef = setInterval(() => {
if (timer === 3) {
clearInterval(timerRef);
closeHandler(index);
} else {
console.log("timer", timer);
setTimer(timer + 1);
}
}, 1000);
}, []); // only run on mount
return (<div className="notifPopup">
<span className=""></span>
<p>{notif.message}</p>
<span className="absolute bottom-2 right-8 text-xs text-oldLace">{`closing in ${timer}s`}</span>
</div>);
};
为什么 setInterval
在控制台中打印 0
流而不更新 DOM?
由于关闭,您正在登录、比较和设置过时值。
在相关问题中查看更多use cases。
useEffect(() => {
// timerRef from useRef
timerRef.current = setInterval(() => {
setTimer((prevTimer) => prevTimer + 1);
}, 1000);
}, []);
useEffect(() => {
console.log("timer", timer);
if (timer === 3) {
clearInterval(timerRef.current);
}
}, [timer]);
查看 the code for useInterval in react-use。检查此包中的不同挂钩可以大大提高您对挂钩的理解。
import { useEffect, useRef } from 'react';
const useInterval = (callback: Function, delay?: number | null) => {
const savedCallback = useRef<Function>(() => {});
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
if (delay !== null) {
const interval = setInterval(() => savedCallback.current(), delay || 0);
return () => clearInterval(interval);
}
return undefined;
}, [delay]);
};
export default useInterval;
和docs中描述的用法:
import * as React from 'react';
import {useInterval} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);
const [isRunning, toggleIsRunning] = useBoolean(true);
useInterval(
() => {
setCount(count + 1);
},
isRunning ? delay : null
);
return (
<div>
<div>
delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
</div>
</div>
);
};
要在挂载上启动间隔,只需更改 isRunning on mount 的值:
useMount(()=>{
toggleIsRunning(true);
});
我在这里进行了一些问答,但无法理解我做错了什么。以下组件在控制台中打印 0
s,但未按预期更新 DOM。
const NotifPopup = ({ notif, index, closeHandler }) => {
const [timer, setTimer] = useState(0);
useEffect(() => {
const timerRef = setInterval(() => {
if (timer === 3) {
clearInterval(timerRef);
closeHandler(index);
} else {
console.log("timer", timer);
setTimer(timer + 1);
}
}, 1000);
}, []); // only run on mount
return (<div className="notifPopup">
<span className=""></span>
<p>{notif.message}</p>
<span className="absolute bottom-2 right-8 text-xs text-oldLace">{`closing in ${timer}s`}</span>
</div>);
};
为什么 setInterval
在控制台中打印 0
流而不更新 DOM?
由于关闭,您正在登录、比较和设置过时值。
在相关问题中查看更多use cases。
useEffect(() => {
// timerRef from useRef
timerRef.current = setInterval(() => {
setTimer((prevTimer) => prevTimer + 1);
}, 1000);
}, []);
useEffect(() => {
console.log("timer", timer);
if (timer === 3) {
clearInterval(timerRef.current);
}
}, [timer]);
查看 the code for useInterval in react-use。检查此包中的不同挂钩可以大大提高您对挂钩的理解。
import { useEffect, useRef } from 'react';
const useInterval = (callback: Function, delay?: number | null) => {
const savedCallback = useRef<Function>(() => {});
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
if (delay !== null) {
const interval = setInterval(() => savedCallback.current(), delay || 0);
return () => clearInterval(interval);
}
return undefined;
}, [delay]);
};
export default useInterval;
和docs中描述的用法:
import * as React from 'react';
import {useInterval} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);
const [isRunning, toggleIsRunning] = useBoolean(true);
useInterval(
() => {
setCount(count + 1);
},
isRunning ? delay : null
);
return (
<div>
<div>
delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
</div>
</div>
);
};
要在挂载上启动间隔,只需更改 isRunning on mount 的值:
useMount(()=>{
toggleIsRunning(true);
});