useCallback이 React 19에 새로 추가된건 아니고 훨씬 이전부터 있었지만 다시 한번 정리하는 차원에서 포스팅한다.
useCallback은 리렌더간 함수의 정의를 캐시하게 하는 훅(lets you cache a function definition between re-renders)이다.
성능 최적화를 위한 메모이제이션 기법 중에 하나로 useMemo와 대조되는데, useMemo는 후속 포스팅에서 정리하는 것으로 하고 이 포스팅에서는 useCallback에 집중한다.
useCallback의 기본적인 구조는 이렇다.
const cachedFn = useCallback(fn, dependencies)
두개의 인수를 전달받는데, fn은 콜백함수로 캐시하고자 하는 함수 자체이다. 이 함수는 메모이제이션 되어 디펜던시가 변화하지 않으면 메모리에 저장된 것을 그대로 다시 반환한다. dependencies는 fn에서 참조하는 모든 reactive values로 fn이 새로 호출되는 시점을 결정한다.
가령
"use client";
import { useState } from "react";
export default function Counter() {
const [ counter, setCounter ] = useState<number>(0);
const handleCounter = () => {
setCounter(counter + 1);
}
return (
<>
<div>{counter}</div>
<button onClick={handleCounter}>+1</button>
</>
)
}
이러한 코드는 버튼을 클릭했을 때 handleCounter 함수가 호출되고, counter를 set하는 함수에 의해 컴포넌트가 리렌더링 된다.
handleCounter를 useCallback에 집어넣었을 때,
const handleCounter = useCallback(() => {
setCounter(counter + 1);
console.log(`${counter}에 1을 더함.`);
}, [])
dependencies에 아무것도 들어있지 않기 때문에 한번은 더해지지만 그 다음에 다시 호출했을 때는 더 이상 더해지지 않는다.

콘솔에 찍어보면 counter가 계속 0인 것을 알 수있다.
다시 말해서 useCallback은 컴포넌트가 리렌더링 되더라도 함수가 초기화 되는 것을 막아주는 것이다.
컴포넌트가 처음 렌더링 되었을 때 handleCounter라는 함수 객체를 만들어 초기화 해주고, 이후 렌더링에서는 handleCounter가 새로운 함수 객체를 할당 받는 것이 아니라 이전에 미리 할당 받은(메모이제이션된) 함수를 계속해서 가지고 있는 상태로 사용하는 것이다(재사용).
이는 useEffect를 사용해보면 명확하게 알 수 있다.
const handleCounter = useCallback(() => {
setCounter(counter+1);
console.log(`${counter}에 1을 더함.`);
}, []);
useEffect(() => {
console.log("handleCounter가 재할당됨.")
}, [handleCounter])
이렇게 코드를 추가했을 때
초기 렌더링 시에는

이와 같이 처음에 함수를 한번 할당해주고 +1 버튼을 눌렀을 때 함수가 메모이제이션 되어 값이 변화하지 않는 것을 알 수 있다.
dependencies에 counter 변수를 추가해주면 counter 변수가 바뀔 때마다 함수 객체를 새로 할당하여 주므로 값이 계속 바뀌는 것을 확인할 수 있다.
const handleCounter = useCallback(() => {
setCounter(counter+1);
console.log(`${counter}에 1을 더함.`);
}, [counter]);
useEffect(() => {
console.log("handleCounter가 재할당됨.")
}, [handleCounter])
이렇게 counter를 dependencies에 추가해주면

함수가 계속 재할당되고, 값이 변화하는 것을 확인할 수 있다.
'기술스택 > React.js' 카테고리의 다른 글
[React 19] useEffect (1) | 2025.03.26 |
---|---|
[React 19] useContext (0) | 2025.03.25 |
[React 19] useActionState (1) | 2025.03.22 |
[React.js] 이미지 / 파일 업로더 구현 (0) | 2022.05.05 |
[React.js] React Router 기본, 중첩 Router 사용하기 (0) | 2022.05.03 |