리액트

[React] useCallback, Meomoization

코딩하는둥이 2025. 4. 29. 11:18

useCallback이란?

 : 컴포넌트가 리렌더링될 때마다 새로 함수를 만들지 않고, 이전에 생성한 동일한 함수 인스턴스를 재사용할 수 있게 해줍니다

 

memoizedCallback은 의존성 배열 [a, b]에 명시된 값이 바뀔 때만 새로 생성됩니다. a와 b가 변경되지 않으면, 이전에 만들어진 함수 인스턴스를 계속 재사용합니다

const memoizedCallback = useCallback(
	() => {
    	doComething(a,b);
    },
    [a,b],
);

 

useCallback의 두 번째 인자인 의존성 배열(dependency array)에 포함된 값이 변경될 때만 새로운 콜백 함수가 생성됩니다

const memoizedCallback = useCallback(
	() => {
    	doComething(a,b);
    },
    [a,b],
);

useEffect(() => {
	memoizedCallback()
}, [memoizedCallback])

 

위 아래 같은 코드입니다.

useEffect(() => {
	doComething(a,b);
}, [a,b])

 

즉, a 또는 b가 바뀔 때만 콜백 함수가 새로 만들어지고, useEffect도 그때만 실행됩니다

 

Meomoization 

 : 프로그램에서 동일한 입력값에 대해 반복적으로 연산이 필요한 경우, 그 결과값을 임시 저장(캐싱)해 두었다가 같은 입력이 들어오면 저장된 결과를 바로 반환하는 최적화 기법입니다. 즉, "이미 계산한 값은 다시 계산하지 않고 저장된 값을 재사용"하여 프로그램을 더 빠르게 동작하게 만듭니다

 

캐싱

 : 임시적으로 결과를 저장하는 공간입니다.

 

Meomoization 사용 전

Recursion

 : 함수가 자기 자신을 다시 호출하는 프로그래밍 기법입니다. 즉, 함수 내부에서 자기 자신을 반복적으로 호출하면서 문제를 더 작은 문제로 쪼개어 해결하는 방식입니다.

 

n이 1 이하일 때는 1을 반환합니다. (종료 조건) 그렇지 않으면, fib(n-1)과 fib(n-2)를 재귀적으로 호출해서 그 결과를 더한 값을 반환합니다.

const fib = n => {
	if (n <= 1) return 1
    return fib(n-1) + fib(n - 2)
}

 

Meomoization 사용 후

const fib = (n, memo = {}) => {
  if (n in memo) return memo[n]; // 캐시된 값이 있으면 바로 반환
  if (n <= 1) return 1;          // 종료 조건
  
  // 계산 결과를 캐시에 저장
  memo[n] = fib(n - 1, memo) + fib(n - 2, memo);
  return memo[n];
};

 

useMemo()

 : 컴포넌트가 리렌더링될 때 "비용이 많이 드는 계산 결과"를 메모이제이션(캐싱)하여, 의존성(dependency)이 바뀌지 않으면 이전에 계산한 값을 재사용하도록 해줍니다.

 

 

a와 b가 변경될 때만 computeExpensiveValue(a, b)가 실행되고, 그렇지 않으면 이전에 계산한 값을 그대로 반환합니다.

const memoizedValue = useMemo(() => computEcpensiveValue(a,b), [a,b]);

 

 

 React.memo

 : 함수형 컴포넌트의 결과를 "메모이제이션(memoization)"하여, 동일한 props가 전달되면 컴포넌트를 다시 렌더링하지 않고 이전에 렌더링한 결과를 재사용하는 고차 컴포넌트(Higher Order Component, HOC)입니다

 

const MyComponent = React.memo(function MyComponent(props) {

};

 

React.memo로 감싸면, props.value가 바뀌지 않는 한 MyComponent는 리렌더링되지 않습니다.

// 일반 함수형 컴포넌트
function MyComponent(props) {
  return <div>{props.value}</div>;
}

// React.memo로 감싸서 메모이제이션 적용
export default React.memo(MyComponent);

 

복잡한 객체나 배열 props의 경우, 커스텀 비교 함수를 사용해 비교 방식을 세밀하게 제어할 수 있습니다

const MyComponent = React.memo(function MyComponent(props) {
  // ...컴포넌트 내용...
}, (prevProps, nextProps) => {
  // true를 반환하면 리렌더링하지 않음, false면 리렌더링
  return prevProps.value === nextProps.value;
});