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이 필요한 상황
- 자식 컴포넌트에 함수를 props로 전달할 때
Copyconst ParentComponent = () => {
const handleClick = useCallback(() => {
console.log('버튼 클릭')
}, [])
return <ChildComponent onClick={handleClick} />
}
- useEffect의 의존성 배열에 함수가 포함될 때
CopyuseEffect(() => {
fetchUsers();
}, [fetchUsers]);
주의사항
불필요한 사용 피하기
모든 함수에 useCallback을 적용하는 것은 오히려 성능을 저하시킬 수 있다.
다음과 같은 경우는 useCallback이 불필요하다.
- 컴포넌트 내부에서만 사용되는 함수
- 자주 변경되는 의존성을 가진 함수
- 간단한 계산을 수행하는 함수
의존성 배열 관리
의존성 배열을 비워두면([]) 컴포넌트 마운트 시에만 함수가 생성된다. 하지만 함수가 특정 상태나 props에 의존한다면, 반드시 의존성 배열에 포함시켜야 한다.
성능 최적화 팁
- React.memo()와 함께 사용하기
Copyconst MemoizedChild = React.memo(ChildComponent)
- 객체 의존성은 useMemo 활용하기
Copyconst memoizedValue = useMemo(() => ({
key: value
}), [value])
성능 최적화는 측정 가능한 문제가 있을 때만 해야한다. 과도한 최적화는 코드를 더 복잡하게 만들 수 있고 오히려 성능을 저하시킬 수 있다.