❓ 정의
- 함수를 메모이제이션하는 훅으로, 동일한 의존성 배열을 가지는 한 매번 새로운 함수가 생성되는 것을 방지하는 역할을 한다.
▶ 기본 사용 예시
const memoizedCallback = useCallback(callbackFunction, [dependencies]);
첫 번째 인자로 메모이제이션할 함수를 받고, 두 번째 인자로 의존성 배열을 받는다.
❗ 사용이유
✅ 불필요한 렌더링 방지 -> 성능 최적화
- React에서 함수는 컴포넌트가 리렌더링될 때마다 새로 생성되는데, useCallback을 사용하면 의존성이 변경되지 않는 한 동일한 함수 객체를 재사용할 수 있다!
💥 주의
1️⃣ 모든 함수에 useCallback을 적용할 필요는 없음!
- 불필요하게 사용하면 오히려 성능이 저하될 수 있다.
2️⃣ 의존성 배열을 정확하게 설정해야 함!
- useCallback 내부에서 사용하는 state나 props를 의존성 배열에 추가하지 않으면 최신 값을 반영하지 못할 수 있다.
✅ useCallback이 필요한 경우
1️⃣ 자식 컴포넌트에 함수를 props로 전달할 때
- 부모 컴포넌트가 리렌더링될 때마다 새로운 함수 객체가 생성되면, React.memo가 적용된 자식 컴포넌트라도 불필요하게 다시 렌더링된다.
import React, { useState, useCallback } from "react";
const Child = React.memo(({ onClick }) => {
console.log("Child 렌더링!");
return <button onClick={onClick}>클릭</button>;
});
export default function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("버튼 클릭!");
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
<Child onClick={handleClick} />
</div>
);
}
하지만 useCallback을 사용하면 handleClick이 리렌더링될 때마다 새로 생성되지 않으므로 Child 컴포넌트가 불필요하게 렌더링되지 않는다!
2️⃣ 함수를 useEffect의 의존성으로 넣어야 할 때
- useEffect에서 특정 함수를 의존성으로 포함해야 하는 경우, 함수가 리렌더링될 때마다 새로 생성되면 useEffect가 불필요하게 실행될 수 있다.
import React, { useState, useEffect, useCallback } from "react";
export default function App() {
const [count, setCount] = useState(0);
const logMessage = useCallback(() => {
console.log(`현재 카운트: ${count}`);
}, [count]);
useEffect(() => {
logMessage();
}, [logMessage]); // useCallback을 사용하지 않으면 매번 useEffect 실행됨
return <button onClick={() => setCount(count + 1)}>증가</button>;
}
- 하지만 useCallback을 사용하면 같은 함수 객체를 유지하여 useEffect가 불필요하게 실행되는 것을 방지할 수 있다!
- logMessage가 useCallback으로 감싸져 있어서 count가 변경될 때만 함수가 변경된다.
3️⃣ 이벤트 핸들러가 빈번하게 재생성될 때
- 렌더링이 자주 발생하는 컴포넌트에서 이벤트 핸들러가 자주 생성되는 경우, 성능 최적화에 좋다.
✅ useCallback이 불필요한 경우
1️⃣ 컴포넌트가 자주 리렌더링되지 않는 경우
- useCallback은 함수 객체의 동일성을 유지하는 것일 뿐, 실행 속도를 빠르게 해주는 것은 아니므로, 함수 재생성이 성능 저하를 유발하지 않는다면 굳이 사용할 필요 없다.
2️⃣ props로 함수를 전달하지 않는 경우
- useCallback은 함수 참조 동일성을 유지하는 것이 목적이므로, 컴포넌트 내부에서만 사용하는 함수라면 useCallback을 사용할 필요가 없다.
3️⃣ 불필요하게 사용하면 오히려 성능 저하
- useCallback도 내부적으로 메모이제이션을 수행하므로 메모리 사용량이 증가할 수 있다.
- 함수 생성 비용보다 useCallback 자체의 비용이 더 크다면 오히려 성능이 나빠질 수도 있다.
'React' 카테고리의 다른 글
[React] Zustand의 Selector + shallow (0) | 2025.03.30 |
---|---|
[React] useMemo, useCallback (+캐싱) (0) | 2025.03.30 |
[React-Query]prefetchQuery (0) | 2025.02.25 |
useEffect의 의존성 배열 (0) | 2024.03.10 |
useRef (0) | 2024.03.10 |