Front-end/React
useCallback과 useMemo의 차이
mooyou
2024. 12. 4. 13:46
728x90
300x250
useCallback과 useMemo 훅에 대해서 알아봤다.
둘 다 메모이제이션 기능을 제공하고 얼핏 같은동작을 하는것 같지만 사용하는 목적과 반환값이 다르다.
구체적으로 알아보자
1. useCallback
- 사용 목적 : 함수를 메모이제이션하여 동일한 함수 인스턴스를 재사용한다.
- 주요 사용 이유 : 함수를 자식 컴포넌트에 props로 전달할 때, 매번 새로운 함수가 생성되지 않도로고 하고 불필요한 렌더링 방지
기본 문법
const memoizedCallback = useCallback(() => {
// 함수 로직
}, [dependencies]);
memoizedCallback : 메모이제이션된 함수
dependencies : 이 배열의 값이 바뀔 때만 함수가 새로 생성된다.
예시 : useCallback 사용
아래 예시는 자식 컴포넌트가 부모로부터 전달받은 함수로 인해 불필요하게 리렌더링되는 문제를 해결한다.
import React, { useState, useCallback } from 'react';
const Child = React.memo(({ onClick }) => {
console.log('Child rendered');
return <button onClick={onClick}>Click Me</button>;
});
const Parent = () => {
const [count, setCount] = useState(0);
// 매 렌더링마다 새 함수가 생성됨 -> 자식이 불필요하게 렌더링됨
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []); // 의존성 배열이 없으므로 항상 같은 함수 반환
return (
<div>
<button onClick={() => setCount((prev) => prev + 1)}>Increase Count</button>
<Child onClick={handleClick} />
<p>Count: {count}</p>
</div>
);
};
export default Parent;
React.memo: 자식 컴포넌트가 props가 바뀌지 않으면 렌더링을 방지.
useCallback : handleClick함수가 새로생성되지 않으므로, Child가 불필요하게 리렌더링되지 않음
2. useMemo
- 사용 목적 : 값을 메모이제이션하여 계산량이 많은 작업을 반복하지 않도록 한다.
- 주요 사용 이유 : 계산량이 많은 작업의 결과를 메모이제이션하여 성능을 최적화, 컴포넌트가 재렌더링될 때 불필요한 계산을 방지
기본 문법
const memoizedValue = useMemo(() => {
// 계산 로직
return computedValue;
}, [dependencies]);
memoizedValue : 메모이제이션된 값
dependencies : 이 배열의 값이 바뀔 때만 값을 다시 계산
예시 : useMemo 사용
아래 예시는 계산량이 많은 작업을 useMemo로 최적화한 사례이다.
import React, { useState, useMemo } from 'react';
const heavyComputation = (num) => {
console.log('Computing...');
return num * 2;
};
const App = () => {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
// count가 변경될 때만 계산 수행
const computedValue = useMemo(() => heavyComputation(count), [count]);
return (
<div>
<button onClick={() => setCount((prev) => prev + 1)}>Increase Count</button>
<p>Computed Value: {computedValue}</p>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type something"
/>
</div>
);
};
export default App;
havyComputation은 count가 변경될 때만 실행된다.
input값이 변경되어도 heavyComputation은 다시 호출되지 않는다.
3. useCallback vs useMemo
useCallback | useMemo | |
리턴값 | 메모이제이션된 함수 | 메모이제이션된 값 |
주요 사용 사례 | - 함수를 자식 컴포넌트에 전달 - 불필요한 렌더링 방지 |
- 무거운 계산 작업 - 값이 재계산 최소화 |
의존성 배열 | 함수가 재생성될 조건 지정 | 값이 재계될 조건 지정 |
4. 간단한 비교 예시
같은 코드를 useCallback과 useMemo로 비교해보자
useCallback 사용
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
useMemo 사용
const memoizedFunction = useMemo(() => {
return () => console.log('Clicked');
}, []);
- 둘 다 비슷하게 작동하지만, useCallback은 함수 자체를 메모이제이션하고, useMemo는 값을 생성해 반환한다.
- useMemo로도 함수를 생성할 수 있지만, 함수에 특화된 작업은 useCallback을 사용하는 것이 더 명확하고 의도를 드러낸다.
728x90
반응형