useMemo
useMemo는컴포넌트 최적화를 위해 사용하는 React Hook이다.
예제 - useMemo를 사용하지 않는 컴포넌트
function MainComponent(){
console.log("MainComponent 렌더링");
const [nickname, setNickname] = React.useState('');
const [count1, setCount1] = React.useState(0);
const [count2, setCount2] = React.useState(0);
const total = count1+count2;
return (
<>
<h1>useMemo 예제</h1>
닉네임 : <input onChange={e=>setNickname(e.target.value)}/>
<hr/>
<p>설정된 닉네임은 {nickname}입니다</p>
<hr/>
<button onClick={()=>setCount1(count1+1)}>click : {count1}</button>
<button onClick={()=>setCount2(count2+1)}>click : {count2}</button>
<h3>총 클릭 횟수 : {total}</h3>
</>
);
}
const app = ReactDOM.createRoot(document.querySelector("#app"));
app.render(<MainComponent/>);
MainComponent의 구조는 다음과 같다.
state로 선언된 nickname
, count1
, count2
가 변경될 경우 <MainComponent/>
는 다시 렌더링을 실시한다. 렌더링을 실시하면 모든 코드를 다시 실행하며, total 역시 다시 계산된다.
현재 상황에서는 state가 적어서 심각하게 느껴지지 않겠지만 디테일하게 살펴보면 nickname
과 total은 전혀 상관이 없는 데이터이다. 따라서 컴포넌트의 성능 저하가 발생하며 규모가 커질 수록 성능 저하로 발생하는 낭비는 심해질 것이다.
예제 - useMemo를 사용하는 컴포넌트
count1
, count2
가 변경되는 경우만 total이 변경되도록 처리하기 위해서 다음과 같이 React.useMemo를 사용한다.
const total = React.useMemo(()=>count1 + count2, [count1, count2]);
전체 코드는 다음과 같다.
function MainComponent(){
console.log("MainComponent 렌더링");
const [nickname, setNickname] = React.useState('');
const [count1, setCount1] = React.useState(0);
const [count2, setCount2] = React.useState(0);
const total = React.useMemo(()=>{
console.log("total 재계산");
return count1+count2;
}, [count1, count2]);
return (
<>
<h1>useMemo 예제</h1>
닉네임 : <input onChange={e=>setNickname(e.target.value)}/>
<hr/>
<p>설정된 닉네임은 {nickname}입니다</p>
<hr/>
<button onClick={()=>setCount1(count1+1)}>click : {count1}</button>
<button onClick={()=>setCount2(count2+1)}>click : {count2}</button>
<h3>총 클릭 횟수 : {total}</h3>
</>
);
}
const app = ReactDOM.createRoot(document.querySelector("#app"));
app.render(<MainComponent/>);
실행한 뒤 콘솔을 확인하면 total 재계산이라는 글자는 count1과 count2가 변경되었을 경우만 실행되는 것을 확인할 수 있다.
결론
React.useMemo()
는 재계산되는 항목에 대한 최적화를 수행한다. 이를 사용하면 컴포넌트의 성능 향상을 가져올 수 있다.