我正在关注Dan Abramov的这篇文章:
https://overreacted.io/making-setinterval-declarative-with-react-hooks/
在本文中,Dan制作了一个自定义的useInterval挂钩,以创建动态的setInterval。
挂钩看起来像这样:
export default function useInterval(callback, delay) {
//this useInterval function will be called whenever the parent component renders.
// on render, savedCallback.current gets set to whatever the callback is, if the callback
// has changed
const savedCallback = useRef();
console.log("called")
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
/**
* Likewise, the set interval is set off,
* and if delay is
*/
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => {
console.log("clearEed!")
clearInterval(id);
}
}
}, [delay]);
}
有一个我不了解的部分,在这里:
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => {
console.log("clearEed!")
clearInterval(id);
}
}
}, [delay]);
我知道,如果更改延迟,则会调用此useEffect。回调被分配为tick,然后,如果delay不为null,则将id设置为SetInterval,其中tick和delay为参数。这一切都说得通。但是接下来发生的事情对我来说很奇怪。我知道useEffect可以在组件卸载时使用return语句,但是为什么我们要清除之前设置的间隔?如果有人可以通过这个方式与我交谈,我将非常感激。
特别是,我非常想帮助您理解以下内容:
if (delay !== null) {
let id = setInterval(tick, delay);
return () => {
console.log("clearEed!")
clearInterval(id);
}
}
我正在这样使用它:
function TimerWithHooks() {
let [count, setCount] = useState(0);
let [delay, setDelay] = useState(1000);
useInterval(() => {
setCount(count + 1);
}, delay)
const handleDelayChange = evt => {
setDelay(Number(evt.target.value))
}
return (
<>
<h1>{count}</h1>
<input value={delay} onChange={handleDelayChange} />
</>
);
}
export default TimerWithHooks;
答案 0 :(得分:0)
我猜想Dan会在组件卸载时清除计时器,但是我认为Beater在函数执行后才这样做。舔点东西:
useEffect(() => {
if (delay !== null) {
let timerId = setInterval(
() => {
savedCallback.current();
clearInterval(timerId);
},
delay
);
}
}, [delay]);
答案 1 :(得分:0)
React何时能准确清除效果? 卸载组件时,React执行清理。但是,正如我们 早先了解到,效果会在每个渲染中运行,而不仅仅是一次。 这就是为什么React还会在下次运行效果之前清除以前渲染中的效果的原因。我们将讨论为什么这有助于避免错误 以及如何选择退出此行为以防产生性能 稍后出现问题。
这意味着每次delay
更改时,效果都会清除以前的效果,因此,每次我们更改延迟时,它将清除计时器,并且在卸载组件时不。这样,我们可以动态调整计时器,而不必担心清除计时器。