useCallback
React Hooks 중 하나로서 useMemo와 같이 Memoization 기법으로 컴포넌트 성능을 최적화시키는 방법이다.
useMemo나 memoization을 모른다면 아래의 링크를 통해 꼭 보고 오자!
useCallback는 첫 번째 인자로 들어간 "콜백함수 그 자체"를 memoization 한다. 즉 콜백함수를 메모리에 저장한다는 말이다.
사용법
useCallback은 첫 번째 인자로는 콜백함수, 두 번째 인자로는 의존성 배열을 받아 총 두 개의 인자를 받는다.
const add = useCallback((num) => {
return num + 1;
}, [value]);
첫 번째 인자는 Memoization할 콜백 함수이다.
두 번째 인자인 의존성 배열은 배열 안의 요소가 업데이트될 때마다 useCallback의 콜백 함수를 재실행시킨다. 콜백 함수를 재실행시킴으로써 메모리에 저장된 함수는 업데이트되어 메모리에 새로 저장된다.
빈 배열일 경우 제일 처음 마운트될 때만 함수를 메모리에 저장하고 그 이후엔 메모리에 있는 함수를 재사용한다.
사용 이유
function App() {
const add = (num) => {
return num + 1;
};
return <div>{value}</div>
}
함수형 컴포넌트인 App이 렌더링되면 내부에 있는 모든 변수 및 함수가 다시 실행되어 초기화되게 된다. 그러면 내부 함수인 add은 App 컴포넌트가 렌더링될 때마다 계속 새로 호출되어야 하고 이는 불필요한 호출을 야기한다.
const add = useCallback((num) => {
return num + 1;
}, [value]);
그렇기 때문에 이때 useCallback을 사용하게 되면 useCallback은 콜백함수를 메모리에 저장하므로 App 컴포넌트가 렌더링되어 add가 호출되어도 이미 메모리에 저장된 함수를 재사용하기 때문에 불필요한 호출을 줄일 수 있다.
즉, 컴포넌트가 처음 렌더링될 때만 add 변수를 초기화해주고 이후에 렌더링될 때는 이미 이전에 할당받은 함수 객체를 재사용하게 된다.
사용 예시
함수 객체는 렌더링 될 때마다 함수 객체가 초기화되고 새로 만들어져서 새로운 주소에 할당되기 때문에 useEffect 입장에서는 의존성 배열에 함수를 넣으면 렌더링 될 때마다 새로운 함수 객체이므로 useEffect의 콜백함수를 호출하게 된다.
이럴 때 이 함수 객체를 useCallback 처리하면 이전에 memoization된 함수 객체의 주소를 가지고 있기 때문에 리렌더링 되었을 때 useEffect의 콜백함수를 호출하지 않게 된다.
function App() {
const [num, setNum] = useState(0);
const tempFunc = useCallback(() => {
console.log(`num :: ${num}`);
return;
}, []);
useEffect(() => {}, [tempFunc]);
return (
<div>
<input type="number" value={num} onChange={(e) => setNum(e.target.value)} />
<button onClick={tempFunc}>확인</button>
</div>
);
}
다음과 같은 코드를 실행시켰을 때 num의 값을 아무리 올려도 확인 버튼을 누르면 console.log 로 찍히는 num의 값이 0인 것을 확인할 수 있다. 코드를 자세히 보면 useCallback의 두 번째 인자가 빈 배열인 것을 알 수 있다. 빈 배열이기 때문에 useCallback은 처음 마운트될 때만 실행되고 그때의 콜백함수 자체를 메모리에 저장했을 것이다. 때문에 처음 마운트되었을 때의 num 값인 0 그대로 저장되어 버튼을 눌렀을 때 num 값이 변했지만 0이 출력된 것이다.
이때 num 값이 변할 때마다 useCallback의 콜백함수에 업데이트를 하고 싶다면 다음과 같이 수정하면 된다.
const tempFunc = useCallback(() => {
console.log(`num :: ${num}`);
return;
}, [num]);
useCallback 내의 변수를 사용했을 때 의존성 배열에 그 변수를 넣지 않게 되면 리렌더링되었을 때 실행되지 않아 변수가 새로운 값으로 변하지 않고 이전(처음)에 메모리제이션된 값으로 유지하게 되기 때문에 내부에 변수가 있다면 의존성 배열에 넣어야 한다.
출처 : 유튜브 별코딩 (직접 듣기 강추!)
'프론트엔드 > React' 카테고리의 다른 글
[React] useContext와 Context API (0) | 2024.01.31 |
---|---|
[React] useState? useReducer? useReducer에 대해 파헤쳐보자 (2) | 2024.01.30 |
[React] Memoization과 useMemo 사용법 (2) | 2024.01.28 |
[React] useRef를 통해 DOM요소에 직접 접근하기 (0) | 2024.01.27 |
[React] useRef는 언제 왜 사용할까? 무한루프 해결방법 (0) | 2024.01.26 |