함수를 메모이제이션하기 위해서 사용되는 hook 함수로 천번째 인자로 넘어온 함수를, 두번째 인자로 넘어온 배열 내의 값이 변경될 때까지 저장해 놓고 재사용 할 수 있게 해준다.
const memoizedCallback = useCallback(함수, 의존성 배열)
React 컴포넌트 함수 안에 함수가 선언이 되어 있다면 이 함수는 해당 컴포넌트가 렌더링 될 떄마다 새로운 함수가 생성된다.
import React, { useEffect, useState } from "react";
export default function App() {
const [number, setNumber] = useState<number>(0);
const someFunction = () => {
console.log(`someFunc: number: ${number}`);
return;
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setNumber(Number(e.target.value));
};
// number 값이 바뀔때마다 useEffect가 실행되는 것을 확인 할 수 있다.
// 즉 값이 변경되어 재 렌더링할 때 someFunction의 메모리 주소가 변경 된다는 것
useEffect(() => {
console.log("someFunction이 변경되었습니다.");
}, [someFunction]);
return (
<div className="App">
<input type="number" value={number} onChange={onChange} />
<br />
<button onClick={someFunction}>Call someFunction</button>
</div>
);
}
이 때 useCallback()을 사용하면, 해당 컴포넌트가 렌더링되더라도 그 함수가 의존하는 값들이 바뀌지 않는 한 기존 함수를 계속 반환한다.
// 의존성 배열은 number로 number 값이 변경되면 초기화되고, 그 외에는 메모이제이션이 된다.
const someFunction = useCallback(() => {
console.log(`someFunc: number: ${number}`);
return;
},[number]);
콘솔창을 보면 숫자 변경할 때와 테마변경 할 때 둘다 콘솔이 찍히는 것을 볼 수 가 있다. 이 때 useCallback을 사용하여 Number 값이 변경 될 때에만 useCallback을 할 수 있게 하면 해결된다.
// 테마 변경을 할때마다 재 렌더링 되면서 함수도 메모리 주소가 바뀌게 되므로
// Box 컴포넌트 내의 useEffect가 렌더링 되는 것이다.
const createBoxStyle = useCallback(() => {
return {
backgroundColor: "pink",
width: `${size}px`,
height: `${size}px`
};
}, [size]);