React.memo는 컴포넌트를 메모이제이션(기억)했다면, useCallback은 인자로 들어오는 함수 자체를 기억한다.
컴포넌트를 React.memo로 메모이제이션했어도, 만일 해당 컴포넌트가 함수를 props로 내려받고 있다면, 상위 컴포넌트에서의 state변화에 따라서 메모이제이션이 풀리고, 리랜더링이 될 수 있다. 함수 또한 일급 객체이기 때문에 props로 내려받은 함수의 변화에도 원본 함수 또한 영향을 받기 때문이다.
그럴 때, 특정함수에 useCallback Hook을 사용하면 특정 함수를 메모리 공간에 저장해놓고, 변경되지 않도록 할 수 있다.
// 변경 전
const initCount = () => {
setCount(0);
};
// 변경 후
const initCount = useCallback(() => {
setCount(0);
}, []);
이렇게 선언을 해놓으면 initCount함수를 props로 내려주어도, 상위 컴포넌트의 변경에 의해 리랜더링이 일어나지 않도록 막을 수 있다.
하지만 useCallback함수는 선언될 당시의 count값에 대한 스냅샷을 가지고, 그것을 기준으로 하기 때문에 state의 변동에 따라 리랜더링 되어야할 상황에서도 리랜더링이 방지되는 경우가 있다.
그 때, 주목해야 하는 state를 의존성 배열(dependency array)에 넣어서 변화를 관측하며, 리랜더링을 컨트롤할 수 있다.