같은 props로 같은 결과를 내는 컴포턴트라면, React.memo로 감싸자 for Performance

일단 급한 분들을 위해 쓰는 법!

const SomeComponent = (props) => {
	return <div>{props.someProp}</div>
}

const areEqual = (prevProps, nextProps) => {
	//-> true를 리턴을 해주면, 리렌더링을 하지 않습니다.
	//default는 false!
	prevProps === nextProps
	//이렇게 통으로 하면, 
	//프랍스가 하나만 바뀌어도 전부 다시 리랜더링이 되겠군요!
}
const MemoizedSomeComponent = React.memo(SomeComponent, areEqual);

Q. useState, useEffect 만 알면 되는것 아닙니까?

간단한 앱이라면 상관 없습니다. 기본적으로 React에서 state가 바뀌면 모든 컴포넌트는 다 리랜더링이 됩니다. 아래를 보시면

import React, {useState, useEffect} from 'react';

const App = ({}) => {
	console.log('app rendering');
	const [cnt, setCnt] = useState(0);

	useEffect(() => {
		console.log('only once')
	}, []);

	return <>
		<div onClick={e => setCnt(cnt => cnt + 1)}>
			Increase + 1
		</div>
		
		<div>
			<span>여기에 복잡한 로직의 최종 결과값이 있다고 해보겠습니다.</span>
		</div>		
	</>	
}

카운트를 눌러 1씩 증가 시키는 경우, console로그를 찍어보면,

"app rendering" 이 버튼을 클릭할 때마다 출력 됩니다. 이유는 cnt 스테이트를 수정했고, cnt가 속한 parent Component는 App이기에, App에 있는 모든 것이 별도의 처리를 하지 않는 한은 모두 리-렌더링이 됩니다. 다행히, useEffect(그리고 dependency는 []으로 된부분)은 한 번만 등록이 되서, 콘솔로그 "only once"는 한 번만 프린트 됩니다.

여기서, 아래 있는 부분을 다음처럼 한 번 컴포넌트로 치환해보겠습니다.

import React, {useState, useEffect} from 'react';

const MyComponent = ({}) => {
	console.log('my component rendering')
	return <div>
		<span>여기에 복잡한 로직의 최종 결과값이 있다고 해보겠습니다.</span>
	</div>		
}

const App = ({}) => {
	console.log('app rendering');
	const [cnt, setCnt] = useState(0);

	useEffect(() => {
		console.log('only once')
	}, []);

	return <>
		<div onClick={e => setCnt(cnt => cnt + 1)}>
			Increase + 1
		</div>
		<MyComponent/>
	</>	
}

잘 보시면 my component라는 부분에도 가장 맨 윗줄에 console로그는 렌더링 그리고 리렌더링이 될때마다 프린트 될텐데, 아직 별다른 조치를 취하지 않았으므로, 클릭을 할 때, 계속 my component rendering도 뜨게 됩니다. 뭐, 간단하니까 리랜더링이 된다고, 느려질 것 없어 보입니다.