[React] useCallback을 언제 사용할까?

G·2025년 1월 31일

React에서 useCallback컴포넌트가 리렌더링될 때 동일한 함수가 새롭게 생성되는 문제를 줄여주는 훅입니다. 하지만 모든 함수에 useCallback을 적용할 필요는 없습니다. 이번 글에서는 useCallback을 언제 사용해야 하고, 언제 불필요한지에 대해 정리해보겠습니다.

✅ useCallback을 사용할 필요가 없는 경우

1. 함수가 useEffect의 의존성이 아닐 때

useEffect 내부에서 특정 함수를 사용하지 않는다면, 해당 함수가 매 렌더링마다 새로 생성되더라도 큰 문제가 되지 않습니다. 따라서 useCallback을 사용할 필요가 없습니다.

2. 함수가 props로 전달되지 않을 때

부모 컴포넌트가 자식 컴포넌트에게 함수를 props로 넘길 경우, 부모가 리렌더링될 때마다 새로운 함수가 생성됩니다. 이때 React.memo를 사용한 자식 컴포넌트가 불필요하게 리렌더링될 수 있습니다. 하지만 props로 전달되지 않는 함수라면 useCallback이 필요 없습니다.

3. 함수가 간단하거나 호출 빈도가 낮아 성능 최적화가 필요하지 않을 때

함수가 간단한 연산을 수행하거나 호출 빈도가 낮다면, 매번 새로운 함수가 생성되더라도 성능에 큰 영향을 미치지 않습니다. 오히려 useCallback을 남용하면 코드의 복잡도만 증가할 수 있습니다.

4. React의 setState 함수에 사용할 필요가 없음

React에서 setState 함수(setAuthVisited, setSignupForm 등)는 내부적으로 동일한 함수 참조를 유지하므로, useCallback을 사용하지 않아도 됩니다. 따라서 setStateuseCallback으로 감싸는 것은 불필요한 최적화입니다.


✅ useCallback이 필요한 경우

1. useEffect 의존성 배열에 포함될 때

useEffect(() => {
  updateData();
}, [updateData]); // updateData가 매번 변경되면 useEffect가 불필요하게 실행됨

위와 같은 경우, updateData가 매 렌더링마다 새로 생성되면 useEffect가 불필요하게 실행됩니다. 이를 방지하려면 useCallback으로 감싸야 합니다.

2. 함수를 props로 전달할 때 (React.memo와 함께 사용)

const Parent = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount((prev) => prev + 1);
  }, []);

  return <Child onClick={handleClick} />;
};

const Child = React.memo(({ onClick }) => {
  console.log("Child 렌더링");
  return <button onClick={onClick}>Click</button>;
});

위 코드에서 handleClickuseCallback 없이 선언하면, Parent가 리렌더링될 때마다 새로운 함수가 생성되어 Child도 불필요하게 리렌더링됩니다. useCallback을 사용하면 이를 방지할 수 있습니다.


🎯 정리

useCallback을 사용할지 말지는 다음 기준을 고려하면 됩니다.

상황useCallback 필요 여부
useEffect 의존성 배열에 포함됨✅ 필요
함수가 props로 전달됨✅ 필요
상태 변경 함수 (setState)❌ 불필요 (React가 보장)
내부에서만 사용하는 함수❌ 불필요
함수가 간단하거나 호출 빈도가 낮음❌ 불필요

🔥 한 줄 요약

"함수가 useEffect의 의존성이 아니고, props로 전달되지 않으며, 성능 최적화가 필요하지 않다면 useCallback은 불필요하다."

앞으로 useCallback을 사용할 때 이 기준을 참고하면 불필요한 최적화를 피하고 코드의 가독성을 높일 수 있을 것입니다. 🚀

profile
Hello!

0개의 댓글