memo
컴포넌트가 재렌더링되면 내부에 있는 자식 컴포넌트는 항상 함께 재렌더링된다.
컴포넌트가 props로 동일한 결과를 렌더링한다면, memo를 호출하고 결과를 메모이징(Memoizing) 하도록 래핑하여 경우에 따라 성능을 향상할 수 있다. memo를 사용하면 react가 컴포넌트를 렌더링하지 않고 마지막으로 렌더링된 결과를 재사용한다.
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
import { memo } from 'react';
const Song = memo(function Song({ title, singer }) {
return (
<div>
<div>Song title: {title}</div>
<div>Singer: {singer}</div>
</div>
);
});
export default Song;
원하는 컴포넌트 정의 부분을 memo로 래핑한다.
그럼 이제 컴포넌트로 전송되는 props가 변하는 경우에만 재렌더링된다.
memo로 감싼 컴포넌트는 불필요한 재렌더링을 피하기 위해 기존 props와 바뀐 props를 비교하는 연산이 수행된다. props 비교 연산은 얕은 비교만을 수행하는 것이 기본 동작이며, 필요시 memo의 두 번째 인자에 비교 함수를 별도로 제공하면 다른 비교 연산을 수행할 수 있다. props가 크고 복잡하면 비교 연산 자체도 부담이 될 수 있으니 반드시 필요한 곳에만 사용할 것을 권장한다.
리액트 공식 문서에도 나와있지만 일반적으로 memo가 유용한 경우가 흔치 않다. props 비교 연산과 더불어 memo는 컴포넌트를 메모리에 저장하기 때문에(memoization) 무분별한 memo 사용은 불필요한 비용만 발생시킨다. 동일한 props로 자주 리렌더링되며, 리렌더링 로직 비용이 큰 경우에만 유용하다. 리렌더링시 눈에 띄는 지연이 없다면 memo는 불필요하다.
useMemo
useMemo를 사용하면 컴포넌트 리렌더링 간에 계산 결과를 캐싱하여 성능을 향상할 수 있다.
const cachedValue = useMemo(calculateValue, dependencies)
초기 렌더링에서 인수 없이 caculateValue의 결과를 반환한다. 다음 렌더링 중에는 마지막 렌더링에서 이미 저장된 값을 반환하거나(dependencies가 변하지 않은 경우), 다시 calculateValue를 호출하고 그 결과를 반환한다. 이와 같이 반환 값을 캐싱하는 것을 memoization이라고 한다. useMemo의 memo는 여기서 나온 것이다.
import { useMemo } from 'react';
function TodoList({ todos, tab }) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
// ...
}
useMemo는 react Hook이기 때문에 컴포넌트 내 최상위에 두어야 한다.
useMemo를 통해 비용이 큰 재계산을 스킵할 수 있다.
useMemo 또한 memo와 마찬가지로 꼭 필요한 곳에만 사용하여야 한다. 사용 중인 계산이 눈에 띄게 느리며(React 공식 문서에서는 1초 이상을 예로 들고 있다.) dependencies가 거의 변하지 않을 때 useMemo를 유용하게 사용할 수 있다.
* useEffect VS useMemo
useEffect > HTML 렌더링 후에 실행됨, dependencies 값이 변할 때마다 콜백 함수를 "실행"
useMemo > HTML 렌더링 될 때 함께 실행됨, 메모리 최적화(성능 향상)만을 목적으로 함.
References
https://react.dev/reference/react/memo
https://react.dev/reference/react/useMemo
https://velog.io/@lky5697/stop-using-usememo-now
'Develop > React' 카테고리의 다른 글
[React] Pagination 구현하기 (1) | 2023.08.14 |
---|---|
[React] CSS 없이 간단한 별점 기능(Star Rating) 구현하기 (0) | 2023.07.27 |
[React] textarea 입력에 따라 높이 자동 조절하기 (0) | 2023.07.22 |
[React] lazy import (0) | 2023.02.22 |
[React] React에서 if 구문 사용하기 (0) | 2023.02.21 |