본문으로 건너뛰기

React의 useCallback 훅 이해하기

함수 메모이제이션과 성능 최적화에 대해 알아보자

useCallback이란?

React의 useCallback 훅은 컴포넌트 렌더링 간에 함수 정의를 메모이제이션하는 도구이다.

컴포넌트가 리렌더링될 때마다 새로운 함수가 생성되는 것을 방지하여 성능을 최적화할 수 있다.

기본 문법

const memoizedCallback = useCallback(
() => {
// 함수 로직
},
[
/* 의존성 배열 */
]
);

실제 사용 예시

다음은 페이지네이션 API를 호출하는 예시입니다:

Copyconst fetchUsers = useCallback(async () => {
const { data } = await axios.get<PaginationResponse<User>>('/users', {
params: { page, size: PAGE_SIZE },
})
setUsers(users.concat(data.contents))
setPage(data.pageNumber + 1)
setNextPage(!data.isLastPage)
setFetching(false)
}, [page])

이 코드에서 page 상태가 변경될 때만 새로운 fetchUsers 함수가 생성됩니다.

useCallback이 필요한 상황

  1. 자식 컴포넌트에 함수를 props로 전달할 때
Copyconst ParentComponent = () => {
const handleClick = useCallback(() => {
console.log('버튼 클릭')
}, [])

return <ChildComponent onClick={handleClick} />
}
  1. useEffect의 의존성 배열에 함수가 포함될 때
CopyuseEffect(() => {
fetchUsers();
}, [fetchUsers]);

주의사항

불필요한 사용 피하기

모든 함수에 useCallback을 적용하는 것은 오히려 성능을 저하시킬 수 있다.

다음과 같은 경우는 useCallback이 불필요하다.

  • 컴포넌트 내부에서만 사용되는 함수
  • 자주 변경되는 의존성을 가진 함수
  • 간단한 계산을 수행하는 함수

의존성 배열 관리

의존성 배열을 비워두면([]) 컴포넌트 마운트 시에만 함수가 생성된다. 하지만 함수가 특정 상태나 props에 의존한다면, 반드시 의존성 배열에 포함시켜야 한다.

성능 최적화 팁

  1. React.memo()와 함께 사용하기
Copyconst MemoizedChild = React.memo(ChildComponent)
  1. 객체 의존성은 useMemo 활용하기
Copyconst memoizedValue = useMemo(() => ({
key: value
}), [value])

성능 최적화는 측정 가능한 문제가 있을 때만 해야한다. 과도한 최적화는 코드를 더 복잡하게 만들 수 있고 오히려 성능을 저하시킬 수 있다.