함수형 컴포넌트에만 가능한 기능
React.memo는 함수형 컴포넌트를 최적화할 수 있다
이 memo는 어떤 역할을 할까?
React.memo는 인자로 들어간 이 컴포넌트에 어떤 props가 입력되는지 확인하고 입력되는 모든 props의 신규 값을 확인한 뒤 이를 기존의 props의 값과 비교하도록 리액트에게 전달합니다
그리고 props의 값이 바뀐 경우에만 컴포넌트를 재실행 및 재평가하게 된다
리고 부모 컴포넌트가 변경되었지만 그 컴포넌트의 props 값이 바뀌지 않았다면 컴포넌트 실행은 건너뛴다
import React, { useState } from 'react';
import DemoOutput from './components/Demo/DemoOutput';
import './App.css';
import Button from './components/UI/Button/Button';
function App() {
console.log('APP RUNNING');
const [showParagraph, setShowParagraph] = useState();
const toggleParagraph = () => {
setShowParagraph((prev) => !prev);
}
return (
<div className="app">
<h1>Hi there!</h1>
// case 1
<DemoOutput show={showParagraph} />
// case 2
<DemoOutput show={false} />
<Button onClick={toggleParagraph}>Toggle Paragraph</Button>
</div>
);
}
export default App;
import React from 'react';
const DemoOutput = (props) => {
console.log('DEMOPUTPUT RUNNING');
return <p>{props.show ? 'This is new!' : ''}</p>
}
export default React.memo(DemoOutput);
case1 의 경우 기존의 값과 계속해서 달라지기 때문에 아래의 DEMOOUTPUT RUNNING" 콘솔 창이 실행되지만
case2 와 같이 false로 하드 코딩 되어 있는 경우는 값이 이전과 달라진 것이 없기 때문에 React.memo() 기능에 따라서 DEMOOUTPUT RUNNING 콘솔 창이 실행되지 않는 것을 확인할 수 있다
즉 불필요한 재렌더링을 피할 수 있다
그런데 왜 모든 컴포넌트에서 사용하지 않는 것인가?
비용이 들기 때문이다.
상위 부모 요소에 위치 시키는 것은 좋은 방법이지만 그 마저도 만약 변경이 자주 일어난다면 적용할 필요가 없을 것이다
모든 컴포넌트를 React.memo로 래핑할 필요는 없다. 그 대신, 컴포넌트 트리에서 잘라낼 수 있는 몇 가지의 주요 컴포넌트 부분을 선택해서 사용하면 된다. 모든 자식 컴포넌트에 대한 작업보다 훨씬 효과적이다.
그럼 이제 Button.js 에 적용해보자
import React from 'react';
import classes from './Button.module.css';
const Button = (props) => {
console.log('BUTTON RUNNING');
return (
<button
type={props.type || 'button'}
className={`${classes.button} ${props.className}`}
onClick={props.onClick}
disabled={props.disabled}
>
{props.children}
</button>
);
};
export default React.memo(Button);
여기에서 원시값과 참조값을 비교할 때
다른 값으로 결과가 나오는 것 때문에 참조값을 사용하는 Button.js 에서 그리고 원시 값을 사용하는 App.js에서 다른 결과가 나타난다.
굉장히 중요한 개념이고 이 때문에 개발자들이 어려움을 겪기도 한다.
그리고 이 문제를 해결하는 방법을 다음 강의에서 알아본다.
'온라인 강의 > React 완벽 가이드 [Udemy]' 카테고리의 다른 글
166. useCallback() 및 해당 종속성 ** (0) | 2023.06.27 |
---|---|
165. useCallback()으로 함수 재생성 방지하기 (0) | 2023.06.27 |
163. 자식 컴포넌트 재평가 자세히 살펴보기 (0) | 2023.06.27 |
162. 컴포넌트 업데이트 실행 중 (0) | 2023.06.23 |
161. 리액트가 실제로 작동하는 방식 (0) | 2023.06.23 |