useEffect(()=>{
setInterval(()=>{console.log("한번만 찍힌다.")}, 1000);
},[])
위와 같이 useEffect 내에서 setInterval을 쓰면 한번만 찍힌다.
왜지? 한번만 실행되도 클로저 내에서 setInterval은 계속 동작할 거라고 생각했는데..
그런데 놀랍게도,
function setInterval(){
...
}
setInterval();
const window={
setInterval: function(){...}
}
window.setInterval(); //window 생략. 글로벌 함수이나 기본적으로 전역객체의 메서드이다.
-> 즉, 클로저를 형성하지 않는다!!
-> 그러니 상위 함수가 사라지면, 같이 그냥 사라진다..
-> 🤔 그럼 어떻게 시작하자마자 setInterval을 쓰게 할까?
export function useInterval(callback, delay) {
//클로저 대용으로 사용하기 위해 ref를 만들어준다.
//-> 함수 컴포넌트가 리렌더링되어도 useRef 객체는 초기화되지 않고 유지되니까!
const savedCallback = useRef();
//초기 세팅
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
setInterval이 실행되고 있는 스코프 내에서 savedCallback을 참조하기 위해!
이렇게 함으로써 setInterval이 실행될 때마다 항상 최신의 callback 함수가 호출된다!