useMemo와 useCallback은 성능 최적화를 위한 리액트 훅으로, 컴포넌트가 불필요하게 다시 렌더링되는 것을 방지하기 위해 사용된다. 이들은 특히 복잡한 컴포넌트에서 유용할 수 있다. 아래에서 조금 더 복작합 예제를 통해 각각의 훅을 자세히 설명하겠다.
useMemouseMemo는 값의 계산을 메모이제이션한다. 즉, 특정 의존성(dependencies)이 변경되지 않는 한, 이전에 계산된 값을 재사용한다. 이 훅은 주로 계산 비용이 큰 함수의 반환값을 메모이제이션하는데 사용된다.
예제: 복잡한 계산이 있는 컴포넌트
import React, { useState, useMemo } from 'react';
function expensiveCalculation(num) {
console.log("Expensive calculation in progress...");
for (let i = 0; i < 1000000000; i++) {} // 일부러 무거운 연산을 추가
return num * 2;
}
function ExampleComponent() {
const [count, setCount] = useState(0);
const [increment, setIncrement] = useState(1);
// useMemo를 사용하지 않는 경우, count가 변경될 때마다 이 비싼 계산이 수행됩니다.
const double = useMemo(() => expensiveCalculation(count), [count]);
return (
<div>
<h1>Double: {double}</h1>
<button onClick={() => setCount(count + increment)}>Increase Count</button>
<button onClick={() => setIncrement(increment + 1)}>Increase Increment</button>
</div>
);
}
export default ExampleComponent;
설명:
expensiveCalculation 함수는 매우 비싼 연산을 수행한다. (예제에서는 일부러 루프를 통해 무거운 연산을 시뮬레이션했다.)useMemo없이 expensiveCalculation을 호출하면, count가 변경될 때마다 이 함수가 다시 계산된다. 하지만 useMemo를 사용하면 count가 변경되지 않는 한 이전에 계산된 값을 재사용하므로 성능이 향상된다.double 값은 count가 변경될 때만 재계산되며, increment가 변경될 때는 useMemo 덕분에 재계산되지 않는다.useCallbackuseCallback은 함수의 메모이제이션을 위해 사용된다. 주로 자식 컴포넌트에 콜백 함수를 전달할 때 유용하다. 의존성이 변경되지 않으면 동일한 함수 인스턴스를 반환하여, 불필요한 자식 컴포넌트의 재렌더링을 방지한다.
예제: 자식 컴포넌트로 콜백을 전달하는 경우
import React, { useState, useCallback } from 'react';
function ChildComponent({ onClick }) {
console.log("Child component rendered");
return (
<button onClick={onClick}>Click me!</button>
);
}
function ParentComponent() {
const [count, setCount] = useState(0);
// useCallback 없이 onClick 함수를 정의하면, ParentComponent가 렌더링될 때마다
// 새로운 함수 인스턴스가 생성됩니다.
const handleClick = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []); // 빈 배열을 의존성으로 주면, 컴포넌트가 처음 마운트될 때만 함수가 생성됩니다.
return (
<div>
<h1>Count: {count}</h1>
<ChildComponent onClick={handleClick} />
</div>
);
}
export default ParentComponent;
설명:
ChildComponent는 onClick 콜백을 props로 받는다.useCallback을 사용하지 않고 handleClick을 정의했다면, ParentComponent가 렌더링 될 때마다 새로운 함수 인스턴스가 생성된다. 그 결과, childComponent도 불필요하게 재렌더링된다.useCallback을 사용하여 handleClick을 메모이제이션하면, ParentComponent가 렌더링될 때 count와 같은 의존성이 변경되지 않으면 동일한 함수 인스턴스를 사용한다. 이는 ChildComponent가 불필요하게 재렌더링되지 않도록 해준다.useMemo는 계산된 값을 메모이제이션하는 데 사용된다.useCallback은 함수의 인스턴스를 메모이제이션하는 데 사용된다.