본문 바로가기
프로그래밍/React

React - useCallback

by hustle-ing 2023. 5. 23.

useCallback이란?

useCallback 또한 useMemo와 마찬가지로 메모이제이션 기법을 활용한 Hook이다. useMemo는 값의 재사용을 위해 사용하는 Hook이라면, useCallback은 함수의 재사용을 위해 사용하는 Hook이다.

function Calculator({x, y}){

	const add = () => x + y;

	return <>
      <div>
					{add()}
      </div>
  </>;
}

해당 컴포넌트가 리렌더링 되더라도 그 함수가 의존하고 있는 값인 x와 y가 바뀌지 않는다고 가정해보자. 그렇다면 함수 또한 메모리 어딘가에 저장해 뒀다가 다시 꺼내서 쓸 수 있다.

/* useCallback를 사용하기 전에는 꼭 import해서 불러와야 합니다. */
import React, { useCallback } from "react";

function Calculator({x, y}){

	const add = useCallback(() => x + y, [x, y]);

	return <>
      <div>
					{add()}
      </div>
  </>;
}

사실 useCallback만 사용해서는 useMemo에 비해 괄목할만한 최적화를 느낄 수는 없다. 왜냐하면 useCallback은 함수를 호출하지 않는 Hook이 아니라, 메모리 어딘가에 함수를 꺼내서 호출하는 Hook이기 때문이다. 따라서 단순히 컴포넌트 내에서 함수를 반복해서 생성하지 않기 위해 useCallback을 사용하는 것은 큰 의미가 없거나 오히려 손해인 경우도 있다. 그러면 언제 사용하는 것이 좋을까?

 

바로, 자식 컴포넌트의 props로 함수를 전달해줄 때 useCallback을 사용하기 좋은 상황이다.

 

 

 

useCallback과 참조 동등성

useCallback은 참조 동등성에 의존한다. React는 JavaScript 언어로 만들어진 오픈소스 라이브러리이기 때문에 기본적으로 JavaScript의 문법을 따라간다. JavaScript에서 함수는 객체이다. 즉, 값 자체를 저장하는게 아니라 값의 주소를 저장하기 때문에 반환하는 값이 같을지라도 일치연산자로 비교했을 때 false가 출력된다.

function doubleFactory(){
    return (a) => 2 * a;
}
  
const double1 = doubleFactory();
const double2 = doubleFactory();
  
double1(8); // 16
double2(8); // 16
  
double1 === double2;  // false
double1 === double1;  // true

double1과 double2에 같은 함수를 할당했음에도 불구하고 메모리 주소 값이 다르기때문에 같다고 보지 않는다.

 

React 역시 마찬가지이다. React는 리렌더링 시 함수를 새로이 만들어서 호출한다. 새로이 만들어 호출된 함수는 기존의 함수와 같은 함수가 아니다. 그러나 useCallback을 이용해 함수 자체를 저장해서 다시 사용하면 함수의 메모리 주소 값을 저장했다가 다시 사용한다는 것과 같다고 볼 수 있다. 따라서 React 컴포넌트 함수 내에서 다른 함수의 인자로 넘기거나 자식 컴포넌트의 props로 넘길 때 예상치 못한 성능 문제를 막을 수 있다.

'프로그래밍 > React' 카테고리의 다른 글

React - useMemo  (0) 2023.05.22
React - Diffing Algorithm  (0) 2023.05.22
React - Virtual DOM  (0) 2023.05.22
React - Styled Components  (0) 2023.04.19
React - Side Effect / Pure Function  (0) 2023.04.03

댓글