count가 바뀌면 setCount 함수가 수행되면서 앱 컴포넌트의 자식 컴포넌트인 카운트 뷰가 리렌더링 된다. 그러면 부모인 앱 컴포넌트가 리렌더링 되면서 자동적으로 텍스트뷰 컴포넌트도 리렌더링된다. 이러한 불필요한 낭비 또는 리렌더링을 막으려면 어떻게 해야 할까?
React.memo 란?
리액트 공식 문서에서 React.memo 는 고차 컴포넌트로서 함수처럼 호출된다고 한다. 그리고 같은 prop을 주면 다시 컴포넌트를 계산하지 않는다. 즉, 리렌더링 하지 않는다는 말이다. 간단하게 React.memo 기능은 같은 연산을 반복하지 않도록 해주는 기능인 것 같다.(물론 자기 자신의 state 가 바뀌면 리렌더링 되어야 하는 건 변함 없다.)
import React, { useEffect, useState } from "react";
const TextView = React.memo(({text}) => {
useEffect(()=>{
console.log(`Update :: Text : ${text}`)
});
return (
<div>{text}</div>
);
});
const CountView = React.memo(({count}) => {
useEffect(()=>{
console.log(`Update :: Count : ${count}`);
})
return (
<div>{count}</div>
);
});
const OptimizeTest = ()=>{
const [count,setCount] = useState(1);
const [text,setText] = useState("");
return (
<div style={{padding: 50}}>
<div>
<h2>count</h2>
<CountView count={count} />
<button onClick={()=>setCount(count+1)}>+</button>
</div>
<div>
<h2>text</h2>
<TextView text={text} />
<input value={text} onChange={(e)=>setText(e.target.value)} />
</div>
</div>
)
};
export default OptimizeTest;
카운트뷰와 텍스트뷰를 만들고 useEffect 를 사용해 마운트 될 때 콘솔에 출력되는지의 여부를 확인하는 코드를 작성했다. 그리고 두 개의 컴포넌트를 앱 컴포넌트의 자식 컴포넌트로 설정했다.
React.memo를 사용하지 않았을 때는 카운트뷰를 변경했을 때 텍스트뷰의 콘솔 또한 출력되고 반대로도 마찬가지였다. React.memo 를 사용한 결과 카운트뷰와 텍스트뷰를 각각 변경해도 자기 자신만 리렌더링 되고 다른 컴포넌트는 리렌더링 되지 않음을 콘솔에서 확인할 수 있었다.
-> 카운트를 변경해도 텍스트뷰에서 출력되지 않는다.