React 최적화 훅
useMemo()
역할: 계산 비용이 큰 값을 메모이제이션(캐싱)해서, 불필요하게 다시 계산하지 않도록 한다.
렌더링 중에 발생하는 연산량이 큰 함수의 결과값을 메모이제이션하며, 이전 결과값을 재사용할 수 있도록 도와준다.
// 간단한 예시
const showNumber = useMemo(()=>getNumber(number),[number]);
// 쓰기 적절한 상황 예시
// list나 keyword가 바뀌지 않으면, 불필요한 filter + sort 연산을 건너뛰고 이전 결과를 재사용
function ExpensiveComponent({ list, keyword }: { list: string[], keyword: string }) {
// filter + sort
const filteredList = useMemo(() => {
return list
.filter(item => item.includes(keyword))
.sort((a, b) => a.localeCompare(b));
}, [list, keyword]);
return (
<ul>
{filteredList.map(item => <li key={item}>{item}</li>)}
</ul>
);
}
useCallback()
역할: 함수를 메모이제이션해서, 매번 새로운 함수 객체가 생성되는 것을 막는다.
컴포넌트가 리렌더링될 때마다 함수를 새로 생성하는 것을 방지하고, 이전에 생성한 함수를 재사용하여 불필요한 렌더링을 줄여준다.
// 간단한 예시
const getItems = useCallback(() => {
return [number, number + 1, number + 2]
}, [number])
// 쓰기 적절한 상황 예시
// React.memo로 props가 안바뀌면 리렌더링 막아줌
const Child = React.memo(({ onClick }: { onClick: () => void }) => {
return <button onClick={onClick}>+</button>;
});
function Parent() {
const [count, setCount] = useState(0);
// useCallback 없으면 count가 바뀔 때마다 새로운 함수 생성
// 그래서 useCallback을 이용해 Child의 props가 리렌더링 되는걸 막아줌
const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<>
<p>{count}</p>
<Child onClick={handleClick} />
</>
);
}
React.memo는 컴포넌트를 메모이제이션 해서 props가 바뀌지 않으면 리렌더링을 막아준다.
React에서 함수는 객체라서, 렌더링될 때마다 새로 만들어진다.
Parent가 리렌더링되면 handleClick은 항상 새로운 함수 객체다. 그래서 props(onClick)가 바뀐 걸로 인식한다.
useCallback으로 함수를 메모이제이션하면 참조가 변하지 않아서, React.memo와 조합했을 때 효과가 나타난다.
그러면 부모함수에서 useCallback으로 함수 리렌더링 막아줬으니까 child는 props가 바뀌는게 없어서 리렌더링 안되니 React.memo가 없어도 되지 않나?
- 부모가 리렌더링되면 → 자식도 기본적으로 리렌더링됩니다.
- useCallback의 역할은 함수 객체를 동일하게 유지하는 것뿐
- React.memo의 역할은 props를 비교해서 props가 이전이랑 똑같네? 굳이 다시 렌더링할 필요 없겠다 하고 막아주는 것
useCallback에서 의존성 배열에 넣을 때
- setState(prev => prev + 1) 처럼 함수형 업데이트를 쓰면 → 의존성 배열을 []로 둬도 괜찮다.
- setState(count + 1) 처럼 외부 변수(count)를 참조하면 → 반드시 [count] 넣어야 안전하다.
주의할 점
- useMemo나 useCallback을 무조건 남발하면 오히려 성능이 더 나빠질 수 있음 → 계산 비용이 크거나, props 최적화가 중요한 경우에만 사용.
- 단순 값이나 함수라면 그냥 매번 새로 만들어도 무방.
'개념 정리' 카테고리의 다른 글
| Cross Site Scripting(XSS) (0) | 2025.09.22 |
|---|---|
| 콜백함수, Promise, Async/await / Ajax, Fetch, Axios (0) | 2025.09.09 |
| 전역 상태 관리에 대해서(Recoil, Zustand, React Query) 이어서 (1) | 2025.05.23 |
| 전역 상태 관리에 대해서(Context API, Redux) (0) | 2025.05.23 |
| React Query에 대해서 (1) | 2025.05.21 |