useCallback
, React.memo
, useMemo
는 리액트에서 불필요한 리렌더링을 줄여 성능을 최적화하기 위한 대표적인 도구입니다. 각각의 목적과 사용하는 이유를 아래와 같이 정리할 수 있습니다.
리액트 컴포넌트는 상위 컴포넌트가 리렌더링되면 자식 컴포넌트도 기본적으로 리렌더링됩니다. 하지만 값이 바뀌지 않았는데도 매번 렌더링하면 성능 낭비가 생깁니다.
이 문제를 해결하기 위해 useCallback
, useMemo
, React.memo
를 사용합니다.
React.memo
– 컴포넌트 리렌더링 막기// components/ExpensiveComponent.tsx
import React from 'react';
type Props = {
value: number;
};
const ExpensiveComponent = ({ value }: Props) => {
console.log('👀 렌더링됨:', value);
return <div>{value}</div>;
};
// React.memo를 쓰면 props가 변경되지 않는 한 다시 렌더링되지 않음
export default React.memo(ExpensiveComponent);
===
비교로 shallow compare(얕은 비교)만 하기 때문에, props가 참조형이면 주의 필요useCallback
– 함수 재생성 방지// App.tsx
import React, { useCallback, useState } from 'react';
import ExpensiveComponent from './components/ExpensiveComponent';
const App = () => {
const [count, setCount] = useState(0);
// 이 함수는 count가 변경되지 않는 한, 같은 참조를 유지함
const handleClick = useCallback(() => {
console.log('Clicked');
}, []);
return (
<div>
<button onClick={() => setCount((c) => c + 1)}>증가</button>
<ExpensiveComponent value={count} />
</div>
);
};
export default App;
useCallback
을 쓰면 같은 함수 참조를 유지할 수 있음