useCallback을 사용하여 함수 재사용하기
전 게시물인 useMemo와 비슷한 Hook입니다.
useMemo는 특정 결과값을 재사용할 때 사용하는 반면, useCallback은 특정 함수를 재사용 하고 싶을 때 사용합니다.
메모이제이션
const memoizedCallback = useCallback(함수, 배열);
첫번째 인자는 함수를 두번째 인자는 넘어온 배열의 값이 변경 될 때까지 저장하여 재사용 할 수 있다.
예를 들어 컴포넌트 함수안에 함수가 선언되어 있다면 이 함수는 컴포넌트가 랜더링 될 때 마다 새로운 함수가 생성된다.
const add = () => x + y;
하지만 useCallback을 사용하면 해당 컴포넌트가 랜더링 되더라도 의존 배열이 바뀌지 않는한 기존 함수를 계속 반환합니다. x와 y 값이 바뀌면 새로운 함수가 생성되어 add에 할당되고, x와 y 값이 바뀌지 않는다면 이전 렌더링때 사용한 함수를 반환한다.
const add = useCallback(() => x + y, [x, y]);
사실 컴포넌트가 랜더링 될때마다 함수를 새로 선언하는 것은 자바스크립트 상에서 성능 상 큰 문제가 없다. 오히려 손해인 경우도 있다.
의미 있게 사용해야 원하는 성능 향상을 기대해 볼 수 있다.
React.memo와 함께 사용하기
useCallback 함수는 자식 컴포넌트의 불필요한 랜더링을 줄이기 위해 React.memo와 함께 사용 할 수 있습니다.
export default React.memo(자식컴포넌트);
자식 컴포넌트를 React.memo로 감싸면 자식컴포넌트는 prop이 변경이 되지 않는 한 리랜더링 되지 않습니다.
prop으로 'toggle' 함수를 넘겨줄 경우 랜더링 될때마다 새로운 toggle 함수를 만들게 되어 자식 컴포넌트는 prop에 변경이 없지만 리렌더링 됩니다
const toggle = () => setToggle(!toggle);
useCallback으로 감싸주게 되면 함수를 재사용하여 자식컴포넌트에 불필요한 랜더링을 막아줍니다.
const toggle = useCallback(() => setToggle(!toggle),[toggle]);