React.memo

2020-03-30

React.memo는 react에서 제공하는 hook이다.
성능을 향상하는데 도움이 되는 hook이다.

React.memo()

React는 이전 렌더링 결과와 비교하여 DOM에 업데이트를 결정한다.
렌더링 결과가 이전과 다르다면 DOM을 업데이트 한다.

React.memo()는 기존에 클래스 컴포넌트에서 shouldComponentUpdate가 내재되어 있다고 생각하면 된다. (PureComponent와 같음)
React.memo()로 래핑을 하면 컴포넌트를 렌더링하고 결과를 메모이징(Memoizing)한다.
다음 렌더링이 일어날 때 props가 같다면 메모이징(Memoizing)된 내용을 재사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
export function NameCard({ name, year }) {
return (
<div>
<div>name: {name}</div>
<div>year: {year}</div>
</div>
);
}

export const MemoizedNameCard = React.memo(NameCard);



// 첫 렌더이다. React는 MemoizedNameCard 함수를 호출한다.
<MemoizedNameCard
name="juyoung"
year="27"
/>

// 다시 렌더링 할 때 React는 MemoizedNameCard 함수를 호출하지 않는다.
// 리렌더링을 막는다.
<MemoizedNameCard
name="juyoung"
year="27"
/>

props로 name, year이 변경되지 않으면 다음 렌더링 때 메모이징 된 내용을 그대로 사용하게 된다.
메모이징을 재사용함으로써 리렌더링할 때 가상 DOM에서 달라진 부분을 확인하지 않아 성능상의 이점을 갖게 된다.

사용해야할 때??

같은 props로 렌더링이 자주 일어나는 함수형 컴포넌트이다.
위에 예시에 있는 코드가 해당한다.


사용하지 말아야 할 때??

props가 변경되는 경우에는 쓸모가 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

function MyApp({ store, cookies }) {
return (
<div className="main">
<header>
<MemoizedLogout
username={store.username}
onLogout={() => cookies.clear()}
/>
</header>
{store.content}
</div>
);
}

function Logout({ username, onLogout }) {
return <div onClick={onLogout}>Logout {username}</div>;
}

const MemoizedLogout = React.memo(Logout);

() => cookies.clear()는 MyApp 컴포넌트가 렌더링될 때마다 새롭게 props를 생성하고 있다.
그래서 React.memo를 사용하더라도 계속 재렌더링하게 된다.
이러한 경우에는 useCallback()을 이용해서 콜백 인스턴스를 보존시키는 방법이 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

function MyApp({ store, cookies }) {
const onLogout = useCallback(() => {
cookies.clear()
}, []);
return (
<div className="main">
<header>
<MemoizedLogout
username={store.username}
onLogout={onLogout}
/>
</header>
{store.content}
</div>
);
}

React.memo를 사용할 때는 props로 사용하는 콜백함수가 이전과 동일한 콜백함수 인스턴스를
넘기는지 확인해야한다.