[React] useCallback

Tae_Tae·2025년 7월 21일

React

목록 보기
14/14

▶️ 개념

React에서 함수가 매번 새로 만들어지는 것을 방지하기 위해 사용하는 Hook이다.

원형

const memoizedFn = useCallback(fn, deps);
  • fn: 캐싱하고 싶은 함수
  • deps: 의존성 배열
    → 이 배열에 있는 값이 변경될 때만 fn이 새로 만들어짐
항목설명
useCallback함수를 메모이제이션(캐싱) 하여 불필요한 재생성을 방지하는 React Hook
언제 사용?특정 함수가 자식 컴포넌트로 전달되거나 의존성에 민감한 작업을 수행할 때
의존성 배열 []배열이 비어 있으면 → 해당 함수는 최초 렌더링 시 한 번만 생성되며, 이후 재생성되지 않음

함수가 매번 새로 만들어지는 이유

React 함수형 컴포넌트는 렌더링될 때마다 전체 함수 본문이 다시 실행되므로, 함수 안에 선언한 함수들도 항상 새로 만들어짐.

function App() {
  const handleClick = () => {
    console.log('clicked');
  };
  return <button onClick={handleClick}>Click</button>;
}

useCallback이 꼭 필요한 상황

자식 컴포넌트에 함수를 props로 전달할 때

<Child onClick={handleClick} />
  • 함수가 계속 새로 만들어지면 props가 계속 바뀐 걸로 인식됨 → 자식이 불필요하게 리렌더링됨
  • React.memo를 써도 의미 없음 → 항상 새로운 함수니까

➡️ 이럴 때 useCallback으로 감싸면 이전 함수와 동일하다고 인식해서 렌더링 최적화 가능

기본 문법

const memoizedFn = useCallback(() => {
  // 어떤 작업
}, [의존값1, 의존값2]);
  • 의존성 배열 안의 값이 바뀔 때만 함수가 새로 생성됨
  • 배열이 []면 → 처음 한 번만 생성되고 절대 다시 생성되지 않음

응용 문법

const fetchData = useCallback(async () => {
  try {
    const res = await fetch('/api/data');
    const data = await res.json();
    // ...
  } catch (error) {
    console.error(error);
  }
}, []);
  • 단순한 메모이제이션이 아니라 비동기 작업(fetch 등)을 포함한 함수를 렌더링마다 새로 만들지 않도록 고정해두는 목적
  • useEffect나 이벤트 핸들러, 클릭 시 데이터 요청에 자주 사용

async로 만든 이유

fetchData 함수는 반드시 Promise를 반환한다.
내부에 await로 비동기 흐름을 동기적으로 쪼깨고, return data로 data를 꺼낼 때도 자동으로 Promise.resolve(data) 상태로 넘어감.

arrow function 사용 이유

  • React 함수형 컴포넌트에서 이벤트 핸들러를 간결하게 표현
  • this 바인딩 이슈 없음

안 써도 되는 상황

  • 함수가 자식 컴포넌트로 전달되지 않을 때
  • 성능 이슈가 눈에 띄지 않는 소규모 앱에서는 굳이 사용하지 않아도 됨
  • 너무 과도하게 쓰면 코드가 지저분해지고 관리 어려움

0개의 댓글