리액트에서 컴포넌트를 개발할 대, 부모 컴포넌트가 재렌더링될 때마다 자식 컴포넌트도 함께 재렌더링되는 경우가 있습니다. 이러한 경우 자식 컴포넌트가 무거운 작업을 수행하는 경우에는 성능 저하가 발생할 수 있습니다. 이런 상황에서 memo와 useMemo를 사용하여 불필요한 재렌더링을 방지할 수 있습니다.
1. memo
(Cart.js)
import {memo, useState} from 'react'
let Child = memo( function(){
console.log('재렌더링됨')
return <div>자식임</div>
})
function Cart(){
let [count, setCount] = useState(0)
return (
<Child />
<button onClick={()=>{ setCount(count+1) }}> + </button>
)
}
Cart.js 파일에 Child 컴포넌트를 만들고, Cart 컴포넌트에 button 을 추가해보겠습니다.
보통의 상황에서 Cart 컴포넌트의 button을 눌러 업데이트가 되면, 자식 컴포넌트인 Child도 함게 재렌더링이 됩니다.
하지만 위의 코드처럼 memo로 컴포넌트를 감싸면, Child로 전송되는 props가 변하는 등의 경우에만 재렌더링됩니다.
memo는 import한 뒤에 원하는 컴포넌트 부분을 let 컴포넌트명 = function(){} 이런식으로 감싸서 만들 수 있습니다.
다만, memo로 컴포넌트를 감쌌을 때에는 기존 props와 바뀐 props를 비교하는 연산이 추가로 진행됩니다.
그러므로 props가 복잡한 경우에는 이것만으로 부담이 될 수 있어 필요한 곳에서만 사용하는 것이 권장됩니다.
2. useMemo
import {useMemo, useState} from 'react'
function calculateResult() {
// 복잡한 계산 로직
}
function Parent() {
const result = useMemo(() => calculateResult(), []);
return (
<div>
{/* result 사용 */}
</div>
);
}
useMemo는 컴포넌트 로드시 1회만 실행하고 싶은 코드가 있을 때 유용합니다.
위의 코드에서 복잡한 계산 로직인 calculateResult() 함수를 호출하는 부분을 useMemo로 감싸면, 해당 함수는 첫 번째 렌더링 시에 한 번만 실행되고 그 결과가 메모리에 저장됩니다. 그 후에 부모 컴포넌트가 재렌더링되어도 해당 함수는 다시 실행되지 않고 이전 결과를 사용합니다.
또한 dependency array를 제공하여 특정 props나 state가 변경될 때만 함수를 다시 실행하도록 할 수도 있습니다.
'React' 카테고리의 다른 글
React 쇼핑몰(Progressive Web App) (0) | 2023.10.31 |
---|---|
React 쇼핑몰(Automatic Batching, useTransition, useDeferredValue) (1) | 2023.10.30 |
React 쇼핑몰(개발자도구, lazy import) (0) | 2023.10.29 |
React 쇼핑몰(localStorage) (1) | 2023.10.29 |
React 쇼핑몰(if문 작성 패턴) (1) | 2023.10.28 |