React를 사용하여 웹페이지를 만들면서 익숙해지기 시작하면 가장 먼저 만나는 문제가 Rerendering 문제입니다. 기능이 동작하는 것 같으나 느낌상, 또는 실제로 화면이 깜빡이는 느낌이 오는 건 나만의 문제는 아닐 겁니다.
깜빡이는 하위 컴포넌트
버튼 이벤트를 사용해서 State를 업데이트할 수 있는 컴포넌트입니다.
import React, { useState } from 'react';
const ChildComponent = ({ text }) => {
console.log('ChildComponent rendered');
return <div>{text}</div>;
};
const ParentComponent = () => {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ChildComponent text="I should not blink" />
</div>
);
};
버튼을 클릭하면 어떤 일이 일어날까요? 콘솔창에 ChildComponent renedered
라는 문구가 계속 찍힐겁니다. 간단한 컴포넌트라서 console 로그로 표현한 것일뿐, 실제 렌더링이 느린 경우는 사람의 눈에 보일 정도로 깜빡일겁니다. 왜냐하면 ParentComponent
가 rerender하면 ChildComponent
도 함께 rerender되기 때문입니다. 이게 함수형 컴포넌트의 특징입니다.
그렇다면 이런 문제를 해결하기 위한 솔루션은 무엇일까요?
리액트에서 React.memo
와 PureComponent
를 사용하여 불필요한 리렌더링을 방지할 수 있습니다. 각각 함수형 컴포넌트와 클래스형 컴포넌트에서 사용됩니다.
React.memo
React.memo는 함수형 컴포넌트의 성능을 최적화하기 위해 사용됩니다. 전달된 props가 변경되지 않으면 컴포넌트를 리렌더링하지 않습니다.
import React, { memo } from 'react';
const ChildComponent = ({ name }) => {
console.log('ChildComponent rendered');
return <div>{name}</div>;
};
export default memo(ChildComponent);
PureComponent
PureComponent는 클래스형 컴포넌트에서 props와 state가 변하지 않으면 리렌더링을 방지합니다. shouldComponentUpdate 메서드를 간단하게 구현한 것과 동일한 역할을 합니다.
import React, { PureComponent } from 'react';
class ChildComponent extends PureComponent {
render() {
console.log('ChildComponent rendered');
return <div>{this.props.name}</div>;
}
}
export default ChildComponent;
💡정리하기
React.memo와 PureComponent 모두 props가 변경되지 않는 경우 컴포넌트가 다시 렌더링되지 않도록 합니다. 이를 통해 성능을 최적화할 수 있습니다. 정리하면 다음과 같습니다.
- React.memo는 함수형 컴포넌트에서 사용하며, PureComponent는 클래스형 컴포넌트에서 사용됩니다.
- React.memo는 기본적으로 얕은 비교를 수행하며, 필요에 따라 비교 함수를 제공할 수 있습니다.
- PureComponent는 shouldComponentUpdate를 기본적으로 구현한 것과 유사하게 동작합니다.
추가예제: React.memo에 비교 함수 사용하기
이와 같이 하면 name이 변경되지 않는 한 리렌더링되지 않게 됩니다. 이를 통해 컴포넌트의 성능을 더욱 세밀하게 제어할 수 있습니다.
const MyComponent = ({ name }) => {
console.log('Rendering MyComponent');
return <div>{name}</div>;
};
const areEqual = (prevProps, nextProps) => {
return prevProps.name === nextProps.name;
};
export default memo(MyComponent, areEqual);
추가 비교: React.useMemo vs React.memo 의 차이점
• React.memo: 컴포넌트 전체의 리렌더링을 방지합니다. props가 변경되지 않는 한 컴포넌트를 다시 렌더링하지 않습니다.
• useMemo: 특정 계산의 결과를 메모이제이션합니다. 의존성이 변경되지 않는 한 캐싱된 값을 반환합니다.
언제 useMemo를 사용해야 하는가?
• 복잡한 계산이 있는 경우
• 동일한 입력에 대해 반복적으로 계산하는 경우
언제 React.memo를 사용해야 하는가?
• 함수형 컴포넌트의 불필요한 리렌더링을 방지하고자 하는 경우
따라서 useMemo는 특정 계산을 최적화하는 데 유용하며, 모든 함수형 컴포넌트에서 반드시 사용해야 하는 것은 아닙니다. 반면, React.memo는 컴포넌트의 리렌더링을 방지하여 성능을 최적화하는 데 사용됩니다. 상황에 맞게 적절한 방법을 선택하여 사용하면 됩니다.
--끝--
'Frontend' 카테고리의 다른 글
Conditional Rendering Component (조건부 렌더링)을 위한 컴포넌트 (0) | 2024.04.07 |
---|---|
Cross-Domain 문제 바로 알기 (0) | 2016.01.22 |