본문 바로가기

카테고리 없음

리액트로 공부하는 클로저

클로저(closure)는 함수와 그것을 아우르는 스코프와의 결합이다. 즉, 클로저를 사용하면 내부 함수에서 외부 함수의 범위에 접근할 수 있다. 클로저는 자바스크립트에서 가장 강력한 기능 중 하나이며, 리액트에서도 널리 사용된다.

리액트에서 클로저를 사용하는 이유

리액트에서 클로저를 사용하는 이유는 다음과 같다.

  • 컴포넌트를 재사용 가능하게 만든다. 클로저를 사용하면 컴포넌트의 상태를 외부에서 접근할 수 있기 때문에, 컴포넌트를 재사용 가능하게 만들 수 있다.
  • 성능을 향상시킨다. 클로저를 사용하면 컴포넌트가 렌더링될 때마다 함수를 다시 생성하지 않아도 되므로, 성능을 향상시킬 수 있다.
  • 코드를 더 읽기 쉽고 유지보수하기 쉽게 만든다. 클로저를 사용하면 함수의 범위를 명확하게 정의할 수 있기 때문에, 코드를 더 읽기 쉽고 유지보수하기 쉽게 만들 수 있다.

클로저의 예시

다음은 클로저의 간단한 예시이다.

function counter() {
  let count = 0;

  function increment() {
    count++;
    return count;
  }

  return increment;
}

const incrementFn = counter();

console.log(incrementFn()); // 1
console.log(incrementFn()); // 2
console.log(incrementFn()); // 3

위 예시에서 incrementFn은 클로저이다. incrementFn은 함수 counter()의 범위에 접근할 수 있기 때문에, count 변수를 증가시킬 수 있다.

리액트에서 클로저 사용하기

리액트에서 클로저는 다음과 같이 사용할 수 있다.

컴포넌트의 상태를 외부에서 접근하기

다음 예시는 클로저를 사용하여 컴포넌트의 상태를 외부에서 접근하는 방법을 보여준다.

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

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

위 예시에서 increment 함수는 클로저이다. increment 함수는 컴포넌트의 상태 변수 count에 접근할 수 있기 때문에, count 변수를 증가시킬 수 있다.

성능 향상

다음 예시는 클로저를 사용하여 성능을 향상시키는 방법을 보여준다.

function Counter() {
  const handleClick = () => {
    // 성능이 좋지 않은 코드
    // setCount(count + 1);
  };

  const memoizedHandleClick = useCallback(() => {
    // 성능이 좋은 코드
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={memoizedHandleClick}>Increment</button>
    </div>
  );
}

위 예시에서 handleClick 함수는 성능이 좋지 않은 코드이다. handleClick 함수는 컴포넌트가 렌더링될 때마다 다시 생성되기 때문에, 성능을 저하시킬 수 있다.

memoizedHandleClick 함수는 useCallback 훅을 사용하여 성능을 향상시킨 코드이다. memoizedHandleClick 함수는 count 변수에 의존성이 있기 때문에, count 변수가 변경되지 않았다면 다시 생성되지 않는다.

코드의 가독성과 유지보수성 향상

다음 예시는 클로저를 사용하여 코드의 가독성과 유지보수성을 향상시키는 방법을 보여준다.

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

  const increment = () => {
    // 성능이 좋지 않고 가독성이 떨어지는 코드
    // setCount(count + 1);

    // 성능이 좋고 가독성이 향상된 코드
    const newCount = count + 1;
    setCount(newCount);
  };

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

위 예시에서 첫 번째 increment 함수는 성능이 좋지 않고 가독성이 떨어지는 코드이다. count 변수의 값을 증가시키기 위해 count + 1 연산을 수행하지만, 코드가 읽기 어렵다.

두 번째 increment 함수는 성능이 좋고 가독성이 향상된 코드이다. count 변수의 값을 증가시킨 후, newCount 변수에 저장한다. 그리고 setCount 함수를 사용하여 newCount 변수의 값을 설정한다. 이 코드는 첫 번째 코드보다 읽기 쉽고 유지보수하기 쉽다.

클로저의 단점

클로저는 강력한 기능이지만, 다음과 같은 단점이 있다.

  • 메모리 누수의 위험이 있다. 클로저는 외부 함수의 범위에 있는 변수에 계속 접근할 수 있기 때문에, 메모리 누수가 발생할 수 있다.
  • 코드의 이해를 어렵게 만들 수 있다. 클로저는 내부 함수에서 외부 함수의 범위에 접근할 수 있기 때문에, 코드의 이해를 어렵게 만들 수 있다.

클로저를 사용할 때는 이러한 단점을 고려해야 한다.

결론

클로저는 자바스크립트에서 가장 강력한 기능 중 하나이며, 리액트에서도 널리 사용된다. 클로저를 이해하고 올바르게 사용하면 리액트 개발을 더 효율적으로 할 수 있다.