아래는 React.memo React 공식 홈페이지에서 발췌한 내용이다.
const MyComponent = React.memo(function MyComponent(props) { /* props를 사용하여 렌더링 */ });
React.memo
는 고차 컴포넌트(Higher Order Component)입니다.당신의 컴포넌트가 동일한 props로 동일한 결과를 렌더링해낸다면,
React.memo
를 호출하고 결과를 메모이징(Memoizing)하도록 래핑하여 경우에 따라 성능 향상을 누릴 수 있습니다. 즉, React는 컴포넌트를 렌더링하지 않고 마지막으로 렌더링된 결과를 재사용합니다.
React.memo
는 props 변화에만 영향을 줍니다.React.memo
로 감싸진 함수 컴포넌트 구현에useState
,useReducer
또는useContext
훅을 사용한다면, 여전히 state나 context가 변할 때 다시 렌더링됩니다.props가 갖는 복잡한 객체에 대하여 얕은 비교만을 수행하는 것이 기본 동작입니다. 다른 비교 동작을 원한다면, 두 번째 인자로 별도의 비교 함수를 제공하면 됩니다.
function MyComponent(props) { /* props를 사용하여 렌더링 */ } function areEqual(prevProps, nextProps) { /* nextProp가 prevProps와 동일한 값을 가지면 true를 반환하고, 그렇지 않다면 false를 반환 */ } export default React.memo(MyComponent, areEqual);
이 메서드는 오직 성능 최적화를 위하여 사용됩니다. 렌더링을 “방지”하기 위하여 사용하지 마세요. 버그를 만들 수 있습니다.
어떤 상황에 성능 최적화가 가능한지 내가 왜 사용하게 되었는지에 대해서 설명하겠다.
위 영상을 보면 3초마다 위 카운트가 증가하는 모습을 볼 수 있다.
(영상 길이를 위해 TIME_OUT을 3초로 설정)
그래서 어떤 상황이냐?
3초 안에 정답을 찾지 못하면 시간 초과로 이동 횟수 증가(HP 감소 등 다양한 로직 가능)를 구현 한 모습이다.
그런데 여기서 문제점은 타임아웃이 되고 난 아래의 타일을 움직이지 않았는데 렌더링이 발생하는 것이다.
해당 화면을 구성하는 GameScreen의 구조를 살펴 보면 아래와 같다.
문제의 원인을 파악해 보면, 부모 컴포넌트의 count
라는 state가 변경되어 자식 컴포넌트 들도 함께 렌더링 되는 것이다.
간단하게 해결 가능하다. 위에 React.memo에 대한 내용을 읽어 보면 딱 여기에 적절한 상황이 아닌가?
이 한줄이면 해결 가능하다
이러한 문제는 내가 그동안 공부 하면서도 많이 발생한 문제였으나, 해당 프로젝트에서는 문제가 되지 않아 무시하고 넘어간 적이 많았던 것 같다. 그래서 이번에는 확실하게 짚고 넘어가고자 글을 쓰게 되었다.