리액트에서 리렌더링이 일어나는 조건은 다음과 같습니다.
1) 컴포넌트의 state가 변경되었을 때
2) 컴포넌트가 상속받은 props가 변경되었을 때
3) 부모 컴포넌트가 리렌더링이 된 경우 자식 컴포넌트는 모두 리렌더링
리액트에서 렌더링이 일어나면 UI를 다시 그려주는 작업을 실시한다.
리렌더링이 자주 일어나면 메모리가 소모되고 비용이 발생하게 된다.
불필요한 렌더링이 발생하지 않기 최적화 작업을 해야할 필요가 있다.
위 이미지에서
1번이 리렌더링 되면 2~7번이 리렌더링
2번이 리렌더링 되면 4~7번이 리렌더링 된다. 하위 컴포넌트 입장에서는
자신들은 바뀐 것이 없는데 리렌더링이 되는 불필요한 소모가 된다.
코드들 통해 더 알아보자
function App() {
console.log("App 컴포넌트가 렌더링되었습니다!");
const [count, setCount] = useState(0);
// 1을 증가시키는 함수
const onPlusButtonClickHandler = () => {
setCount(count + 1);
};
// 1을 감소시키는 함수
const onMinusButtonClickHandler = () => {
setCount(count - 1);
};
return (
<>
<h3>카운트 예제입니다!</h3>
<p>현재 카운트 : {count}</p>
<button onClick={onPlusButtonClickHandler}>+</button>
<button onClick={onMinusButtonClickHandler}>-</button>
<div style={boxesStyle}>
<Box1 />
<Box2 />
<Box3 />
</div>
</>
);
}
export default App;
위 코드에서 App 컴포넌트의 하위 컴포넌트인 Box1~3은 카운트가 변경될 때마다 리렌더링이 일어나게 된다. Box 컴포넌트들은 아무런 변화가 없음에도...
이러한 불필요한 렌더링을 방지하기 위해 React.memo라는 훅이 있다
코드를 통해 사용법을 알아보자
export default React.memo(Box1);
export default React.memo(Box2);
export default React.memo(Box3);
-> 각 컴포넌트의 export 부분에 React.meomo로 Box를 감싸준다.
컴포넌트를 메모리에 저장해두고 필요할 때 가져다 쓰게 된다.
부모컴포넌트의 state 변경으로 인해 props 변경이 일어나지 않는 한
컴포넌트는 리렌더링 되지 않는다.
이것을 컴포넌트 memoization> 이라고 한다.