클로저란?
jhleeWEB edited this page Jun 21, 2022
·
3 revisions
어휘적 범위를 지정하는 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지를 고려한다는 의미
함수가 부모 함수 내에 선언되었다면 그 자식 함수가 closure이다. 클로저의 특징
- 외부함수 스코프에서 내무함수 스코프로 접근 불가능하다.
- 반대로 내무함수는 외부함수 스코프에 접근이 가능하다.
- 외부함수의 실행이 종료된 후에도, 클로저는 외부함수의 스코프에 접근 할 수 있다.
우선 대표적으로 react에서의 클로저를 살펴보자
const Component = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
}
useEffect(() => {
const timer = setTimeout(() => increment(), 1000);
return () => clearTimeout(timer);
},[increment]);
return <div>{count}</div>
}
Component함수는 외부 함수가 될 것이고, increment함수는 내무 함수가 될 것이다. increment함수는 외부함수에서 선언된 지역변수 count에 1을 더하여 dispatch한다. 여기서 increment함수가 클로저이다. 이상황에서는 정상적으로 count올라가는 것을 경험할 수 있다.
그럼 increment함수를 useCallback훅을 활용했을때 어떻게 되는지 확인해보자
const Component = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
},[]);
useEffect(() => {
const timer = setTimeout(() => increment(), 1000);
return () => clearTimeout(timer);
},[increment]);
return <div>{count}</div>
}
위에 코드를 실행하면 이전 현상과 다른 것을 경험할 수 있다. 이유는 useCallback훅을 사용하면서 기존에 increment함수가 더이상 Component의 어휘적 범위에 속하지 않게 된 것이기 때문이다. useCallback의 increment함수를 callback함수로 넘겨줬고, useCallback을 그 callback함수를 감쌓아서 반환해 줬을 것이다. 그렇게 된다면 감싸고있는 함수는 callback의 외부 함수가 되고, callback은 내부함수가 될것이다.
const Component = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
},[count]);
useEffect(() => {
const timer = setTimeout(() => increment(), 1000);
return () => clearTimeout(timer);
},[increment]);
return <div>{count}</div>
}
다시 정상적으로 작동하게 하려면 useCallback 참조배열에 count를 넣어줘야 한다. 그래야 useEffect가 increment의 변화를 감지하며 연속적으로 count가 올라갈것이다.