useCallback
또한 메모이제이션 기법으로 컴포넌트 성능을 최적화 시켜 주는 도구다.
useMemo
는 인자로 전달한 콜백함수에서 이 함수가 리턴하는 값을 메모이제이션 하는 반면, useCallback
은 인자로 전달한 콜백함수 그 자체를 메모이제이션한다.
useCallback(()⇒{}, [deps])
첫 번째 인자: 메모이제이션 할 콜백함수
두 번째 인자: 의존성 배열에 있는 값들이 변경될 때마다 함수에 새로운 함수 객체를 만들어 초기화한다. 함수 내에서 참조하는 state, props가 있다면 배열에 추가해 주면 된다.
의존성 배열에 아무것도 없다면 컴포넌트가 최초 렌더링될 때에만 함수가 생성되며, 그 이후에는 동일한 참조 값을 사용하는 함수가 된다.
**함수를 메모이제이션 하기 위해 쓰는 것이 useCallback
**이라고 생각하면 된다. 이 함수가 다시 필요할 때마다 함수를 새로 생성하는 게 아니라, 그대로 메모리에서 가져와 재사용한다.
자바스크립트에서 함수는 객체의 한 종류이다. 리액트에서 함수형 컴포넌트는 함수이므로, 함수형 컴포넌트가 렌더링 된다는 것은 그 컴포넌트를 나타내는 함수가 다시 호출된다는 것이며, 그럼 컴포넌트 내부에 있는 모든 변수들이 초기화된다.
function Component() {
const calculate = (num) => {
return num+1;
}
return <div>{value}</div>
}
export default Component;
위 예시에서 Component 컴포넌트가 렌더링될 때마다 calculate 함수가 리렌더 된다. 컴포넌트가 처음 렌더링될 때만 이 함수 객체를 만들어서 함수를 초기화해 주고, 이후 렌더링에 calculate 변수가 새로운 함수 객체를 다시 할당받는 것이 아니라 이전에 이미 할당받은 함수 객체를 계속해서 가지고 있으면서 재사용하면 최적화를 할 수 있다.
따라서 위의 코드를 다음과 같이 바꿔서 사용한다.
const calculate = useCallback((num)=>{
return num+1;
}, [item])
만약 2번째 인자인 deps가 변경된다면 calculate 함수는 새로 만들어진 함수 객체로 초기화된다.