리액트 컴포넌트와 클로저의 관계

김현준·2024년 10월 28일
0

리액트 이모저모

목록 보기
21/27

리액트 컴포넌트는 클로저를 사용하여 내부 상태와 props를 유지한다. 특히 함수형 컴포넌트에서 클로저는 다음과 같은 상황에서 매우 유용하다:

1. 상태와 이벤트 핸들러

컴포넌트 내부에서 이벤트 핸들러를 정의할 때, 이 핸들러는 컴포넌트의 상태나 props를 참조하게 되며, 이 참조가 클로저로 유지된다.

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return <button onClick={handleClick}>Count: {count}</button>;
}

위 코드에서 handleClick 함수countsetCount에 대한 클로저를 가진다. 이 덕분에, 버튼을 클릭할 때마다 count의 최신 상태를 참조할 수 있다.

2. 의존성을 가진 useEffect

리액트의 useEffect는 클로저를 이용해 컴포넌트가 처음 렌더링된 시점의 변수나 상태를 기억하고 참조한다.
useEffect의 의존성 배열이 바뀔 때마다 새로운 클로저가 만들어져 최신 상태를 참조하게 된다.

useEffect(() => {
  console.log('Current count:', count);
}, [count]);

3. 클로저 문제와 stale 상태

클로저를 사용할 때 주의할 점은 stale 상태이다. 오래된 클로저를 참조하면 최신 상태를 가져오지 못하고, 이전 값을 참조할 수 있다.
리액트에서는 이를 방지하기 위해 useState의 함수 업데이트 형태 (prevState) => newState나, useRef를 활용하는 방법 등을 제공한다.

리액트 컴포넌트가 클로저인가?

리액트 컴포넌트 자체가 클로저인 것은 아니지만, 컴포넌트 내부에서 정의된 함수들이 클로저가 될 수 있다. 특히 useState, useEffect와 같은 React 훅은 내부적으로 클로저를 사용하여 상태를 관리하고, 이전 렌더의 값을 기억해두는 방식으로 동작한다.

useState의 경우, 상태 변경 함수(setState)가 클로저로 작동하여 컴포넌트의 최신 상태를 지속적으로 참조할 수 있게 한다. 이는 비동기 작업이나 이벤트 핸들러 등에서 이전 상태가 아닌 최신 상태를 항상 유지하는 데 큰 역할을 한다.

따라서, 리액트 컴포넌트는 클로저가 아니지만, 클로저를 사용해 내부의 동작을 관리한다고 볼 수 있다. 클로저를 잘 이해하면 리액트에서 상태 관리, 이벤트 핸들링, 비동기 작업 등을 효과적으로 처리할 수 있다.

useState훅을 클로저로 구현한 예시
실제로는 라이프사이클을 업데이트하는 등 복잡한 로직이 추가되지만 기본적인 모습은 이럴 것이다.

function useState(initialValue) {
    let state = initialValue;return [
        function getState() {
            return state;
        },
        function setState(newValue) {
            state = newValue;
        }
    ];
}const [count, setCount] = useState(0);
ㅤ
console.log(count()); // 0 (업데이트 전)
setCount(1);
console.log(count()); // 1 (업데이트 후)
profile
기록하자

0개의 댓글

관련 채용 정보