useCallback의 탄생 배경
useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용합니다.
함수를 선언하는 것 자체는 메모리도, CPU도 리소스를 많이 차지하는 작업은 아니지만, 한 번 만든 함수를 필요할 때만 새로 만들고 재사용하는 것은 매우 중요합니다.
그 이유는, Virtual DOM에서 불필요한 렌더링을 줄일 수 있기 때문입니다.
예를 들어, 부모 컴포넌트가 자식 컴포넌트에게 함수를 props로 전달할 때, 자식 컴포넌트가 props가 변경될 때마다 새로운 함수를 생성하면 부모 컴포넌트가 리렌더링 됩니다. 이를 해결하기 위해 useCallback을 사용하여 자식 컴포넌트에서 메모이제이션된 함수를 사용할 수 있습니다.
useCallback Hook
useMemo를 기반으로 만들어진 훅인데, useMemo는 특정 결과값을 재사용할 때 사용했다면,
위에서 언급했듯이, useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용합니다.
또한 일반적인 값의 경우 useMemo를 사용하는 것이 편리하지만, 함수의 경우 useMemo를 사용하게 되면 콜백함수에서 또 다른 함수를 리턴하는 형태가 됩니다. 동작상에는 이상이 없지만 문법적으로 다소 보기 불편해진다는 단점이 있어 useCallback 함수를 사용합니다.
const memorizedFunction = useMemo(() => () => console.log("Hello World"), []);
const memorizedFunction = useCallback(() => console.log("Hello World"), []);
예제
import React, { useState, useCallback } from 'react';
function App() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>Increment</button>
</div>
);
}
export default App;
increment 함수는 useState로 관리되는 count 상태를 업데이트 합니다.
여기서 포인트는 increment 함수는 useCallback으로 래핑되었기 때문에, count가 변경될 때만 메모이제이션된 함수를 생성합니다.
이로 인해, 자식 컴포넌트에서 increment 함수를 전달할 때, 같은 함수를 계속해서 재사용할 수 있습니다.
주의할 점은, 함수 안에서 사용하는 상태 혹은 props가 있다면 꼭 deps 배열 안에 포함시켜야 한다는 것입니다. 그렇지 않으면, 함수 내에서 해당 값들을 참조할 때 가장 최신 값을 참조할 것이라고 보장할 수 없기 때문입니다.
참고자료
질문이나 잘못된 점은 댓글로 남겨주세요 :)💖
'React' 카테고리의 다른 글
React 렌더링과 최적화 + React.memo로 재사용여부 판단하기 (0) | 2023.05.07 |
---|---|
[react] useId Hook + 예제 (0) | 2023.04.27 |
[react] useEffect Hook + 예제 (0) | 2023.04.26 |
[react] useReducer Hook + 예제 (0) | 2023.04.26 |
[react] useContext Hook + 예제 (0) | 2023.04.26 |
댓글