React.memo는 아래 포스트를 통해 개념에 대해 간단하게 다뤄본 적이 있습니다.
[React] 리액트 최적화하기
React 참조 개요 – ReactThe library for web and native user interfacesko.react.dev가장 큰 팁: 공식 문서를 잘 읽자. 1. useMemo공식 문서 설명재렌더링 사이에 계산 결과를 캐싱할 수 있게 해주는 React Hook 입니다.
doringri.tistory.com
이번 포스트에서는 React.memo에 대해 더 구체적으로 알아보겠습니다.
배경지식
React 컴포넌트는 부모 컴포넌트가 리렌더링되면 자식 컴포넌트도 함께 리렌더링되는 특징을 가지고 있습니다.
이때, 자식 컴포넌트를 memo로 감싸면 자식 컴포넌트에게 넘기는 props 값의 변화가 없는 한(얕은 비교) 자식 컴포넌트를 리렌더링시키지 않습니다.
React.memo를 쓰기 좋은 경우
- 자식 컴포넌트에게 주는 props 값의 변화는 거의 없으면서, 부모 컴포넌트의 리렌더링이 빈번하게 발생할 때
컴포넌트는 state의 값이 변경될 경우 리렌더링하므로, 부모 컴포넌트의 state 값 변화가 자주 일어난다면 고려할 만합니다.
- 자식 컴포넌트에서 무겁고 비용이 큰 연산을 수행하는 경우
리렌더링될 때마다 해당 연산이 계속 다시 실행된다면, memo를 사용하기 좋습니다.
React.memo를 쓰지 말아야 할 경우
- 자식 컴포넌트에게 주는 props의 값이 자주 바뀌는 경우
이 경우 이전 props의 값과 비교하는 작업이 많이 일어나기 때문에 오히려 성능이 저하될 수 있습니다.
React.memo를 굳이 안 써도 되는 경우
- 자식 컴포넌트 내부에서 리렌더링이 이미 빈번하게 발생하는 경우
이 경우는 React.memo를 사용함으로써 발생하는 가독성 저하를 감수할 만큼의 성능 향상이 없는 경우입니다.
얕은 비교
React.memo는 얕은 비교를 통해 이전 props 값과 현재 props 값의 차이를 확인합니다.
즉, 아래 코드처럼 객체를 props로 내보낼 때는 같아 보이는 객체라 할지라도 메모리 값이 다르므로 다른 객체로 취급하고 리렌더링을 한다는 것입니다.
import { memo, useEffect, useState } from "react";
const Greeting = memo((props: {
name: string
info: {age: number, hobby: string}
}) => {
return <h1>Hello, {props.name}!</h1>;
});
export const MyApp = () => {
const [name, setName] = useState<string>("");
const [info, setInfo] = useState<{age: number, hobby: string}>({age: 10, hobby: "singing"});
useEffect(() => {
setInfo({age: 10, hobby: "singing"});
}, []);
return (
<Greeting name={name} info={info}/>
);
}
이 점을 유의하고 memo를 사용해야 합니다.
방지할 수 있는 방법은 info 객체를 useMemo로 메모이제이션하면 됩니다.
MyApp 컴포넌트를 아래와 같이 바꿀 수 있습니다.
export const MyApp = () => {
const [name, setName] = useState<string>("");
const [age, setAge] = useState<number>(10);
const [hobby, setHobby] = useState<string>("singing");
const info = useMemo(() => (
{age: age, hobby: hobby}
), [age, hobby]);
return (
<Greeting info={info}/>
);
}
age, hobby를 state로 관리하면서 useMemo를 통해 이들의 값이 변할 때만 info의 값을 업데이트시켜주도록 메모이제이션 하였습니다. 그런 info를 props로 전달합니다. 이렇게 하면, 불필요한 리렌더링은 사라지겠지요.
23시 57분이 지나가는 아슬아슬한 상태네요. 3주간의 티스토리 오블완 챌린지 마지막 글이군요.
하루의 마지막, 블로그 글을 쓰는 것만으로도 하루를 조금이나마 의미 있게 보낸 것 같아서 뜻깊은 경험이었습니다.
다른 오블완 챌린저 분들도 모두 수고하셨습니다.
'IT > React & Next.js' 카테고리의 다른 글
| [React] 비즈니스 로직과 UI 분리하기 (0) | 2025.01.12 |
|---|---|
| [React] React Profiler로 성능을 측정해보자 (1) | 2024.11.28 |
| [React] Clean-up 함수에 대해 (feat. useRef) (0) | 2024.11.22 |
| [React] useReducer 사용하기 (1) | 2024.10.29 |
| [React] Jotai 사용해보기 (1) | 2024.10.04 |