ReactJS - useCallback 사용법: 초보자 가이드
안녕하세요, 미래의 React 개발자 여러분! 오늘 우리는 React의 강력한 훅 중 하나인 useCallback에 대해 깊이 다루어보겠습니다. 프로그래밍에 처음 도전하는 분이라면 걱정하지 마세요; 저는 여러분을 단계별로 안내해드릴 것입니다. 여러 해 동안 많은 학생들을 가르쳐온 경험을 바탕으로 말이죠. 이 흥미로운 여정을 함께 시작해보겠습니다!

useCallback는 무엇인가요?
자, 구체적인 내용으로 들어가기 전에 useCallback에 대해 이해해보겠습니다. 쿠키를 만드는 것을 상상해보세요 (이 비유는 정말 좋아요. 누가 쿠키를 좋아하지 않을까요?). 매번 사용하는 특별한 레시피가 있죠. useCallback은 그 레시피를 한 번 작성하고 필요할 때마다 사용하는 것과 같습니다. 매번 기억하려고 노력할 필요 없이요.
React의 용어로는, useCallback은 우리의 애플리케이션 성능을 최적화하기 위해 함수를 메모이즈(기억)하는 훅입니다.
useCallback 훅의 서명
먼저 useCallback을 어떻게 작성하는지 보겠습니다:
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
πανκ! 이 부분이 복잡해 보일 수 있지만, 단계별로 설명해드리겠습니다:
-
memoizedCallback: 이는useCallback이 반환하는 함수입니다. -
() => { doSomething(a, b); }: 이는 메모이즈할 함수입니다. -
[a, b]: 이는 의존성 배열입니다. React가 함수를 다시 생성해야 할 때를 알려줍니다.
이렇게 생각해보세요: React에게 "이 함수를 기억하고, a나 b가 바뀌지 않는 한 새로운 함수를 주지 말아줘"라고 말하는 것입니다.
useCallback 적용하기
이제 useCallback을 간단한 예제로 실제로 사용해보겠습니다:
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<div>
Count: {count}
<button onClick={increment}>Increment</button>
</div>
);
}
이를 단계별로 설명해보겠습니다:
-
useCallback을 React에서 import합니다. -
useState를 사용하여count상태 변수를 생성합니다. -
useCallback을 사용하여increment함수를 정의합니다. 이 함수는count을 1 증가시킵니다. - 빈 배열
[]을 두 번째 인자로 제공하여 이 함수는 절대로 바뀌지 않음을 의미합니다. -
count과 버튼을 렌더하여, 버튼을 클릭할 때increment를 호출합니다.
useCallback의 사용 사례
이제 useCallback을 언제 사용해야 할지 고민이 드실 수도 있습니다. 훌륭한 질문입니다! 몇 가지 일반적인 시나리오를 살펴보겠습니다:
1. 최적화된 자식 컴포넌트에 콜백을 전달하기
자식 컴포넌트가 React.memo로 감싸인 경우를 상상해보세요. 이 컴포넌트에 함수를 전달하고 싶습니다:
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<ChildComponent onClick={handleClick} />
<p>Count: {count}</p>
</div>
);
}
const ChildComponent = React.memo(({ onClick }) => {
console.log("Child rendered!");
return <button onClick={onClick}>Increment</button>;
});
여기서 useCallback은 handleClick이 count이 바뀔 때만 변경되도록 해서 ChildComponent의 불필요한 재랜더링을 방지합니다.
2. useEffect 의존성에 사용하기
useCallback은 useEffect 훅의 의존성으로 사용할 때도 유용합니다:
import React, { useState, useCallback, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
const fetchData = useCallback(() => {
// API에서 데이터를 가져오는 것을 상상해보세요
setTimeout(() => setData("New Data!"), 1000);
}, []);
useEffect(() => {
fetchData();
}, [fetchData]);
return <div>{data ? data : "Loading..."}</div>;
}
이 예제에서 useCallback은 fetchData가 매 랜더링마다 변경되지 않도록 해서 효과가 불필요하게 실행되지 않도록 합니다.
useCallback의 장단점
useCallback의 장점과 단점을 요약해보겠습니다:
| 장점 | 단점 |
|---|---|
| 불필요한 재랜더링을 방지합니다 | 코드가 더 복잡해질 수 있습니다 |
| 자식 컴포넌트의 성능을 최적화합니다 | 과도한 사용이 성능 문제를 일으킬 수 있습니다 |
useEffect 의존성에 유용합니다 |
클로저와 메모이제이션 이해가 필요합니다 |
| 안정적인 콜백을 만듭니다 | 간단한 컴포넌트에서는 큰 이점이 없을 수 있습니다 |
결론
와우! 오늘 많은 내용을 다루었습니다. useCallback은 여러분의 React 도구箱에서 강력한 도구입니다. 하지만 모든 도구처럼, 지혜롭게 사용해야 합니다. React의 여정을 계속하면서, 언제 useCallback을 사용해야 하는 직감을 키워갈 수 있을 것입니다.
최적화는 좋지만, 명확하고 읽기 쉬운 코드는 더 중요합니다. useCallback을 어디서나 사용하的压力을 늦추세요 – 애플리케이션에 적합한 경우에만 사용하세요.
계속 연습하고, 호기심을 가지고, 행복하게 코딩하세요! 그리고 기억하세요, 완벽한 쿠키 레시피를 완성하는 것처럼, React 마스터하기는 시간과 인내가 필요합니다. 여러분이 할 수 있습니다!
Credits: Image by storyset
