리엑트에서는 state
나 관련된 props
가 변경되면 전체가 업데이트(render)된다.
하지만 다음과 같은 문제점을 가지므로,
동일한 props
와 state
에도 같은 결과를 불필요하게 렌더링 한다.
→ 리엑트는 VDOM(Virtual DOM)을 써서 지금 업데이트 될 것과 이전 것을 비교해 실제로 업데이트 해야 하는 것들만 DOM 요소에 업데이트 하기 때문에 성능에 큰 영향은 없다.
componenetDidMount()
와 같이 Component가 마운트될 때마다 호출해주는 함수가 등록되어 있을 때, 이런 함수안에 서버에서 데이터를 받아온다든지 등의 무거운 로직들을 수행한다면 매우 비효율적으로 반복되어질 수 있다.
이를 방지하기 위해 사용되는 것이 PureComponent와 memo이다.
import React, { PureComponent } from 'react';
// Component를 PureComponent로 바꿔주면 된다.
class Cart extends PureComponent {
state={
...
};
render() {
return (
...
);
}
}
export default Cart;
import React, { memo } from 'react';
// 컴포넌트를 memo로 감싸주면 된다.
const Example = memo((props) => {
...
return(
...
);
});
export default Example;
(이 둘은 비슷한 특성을 가지므로 그 중 하나, Pure Component만 다루겠다.)
Pure Component는 state
나 props
에 변화가 없다면 render
함수가 실행되지 않는다. 이는 React.Component
와 달리 shouldComponentUpdate()
를 구현해 props
와 state
를 이용한 얕은(shallow) 비교를 구현한다는 점에서 차이가 있다.
따라서 컴포넌트에 복잡한 자료 구조가 포함되어있다면, 깊은 곳에 차이가 존재함에도 불구하고 차이가 없다고 판단하는 잘못된 결과를 만들어낼 수 있으므로,
props
와 state
의 구조가 간단할 것으로 예상될 때에만 Pure Component
를 상속하고, forceUpdate()
를 사용하거나, 중첩된 데이터들을 빠르게 비교할 수 있도록 불변 객체의 사용을 검토해보자.
Pure Component
의shouldComponentUpdate()
는 컴포넌트의 하위 트리에 대한props
갱신 작업을 수행하지 않으므로, 자식 컴포넌트들이 "순수한지" 확인해야 한다.
컴포넌트를 업데이트 할 때 현재 상태와 새로운 상태를 비교하는 방식에는 두가지가 있다. 그 중 Shallow Comparison을 다시 정리해보자면,
Pure Component인 경우 사용하는 비교 방식으로, 오브젝트의 최상위 reference를 비교해 달라진 점이 있다면 컴포넌트를 업데이트 한다.
Pure Component의 shouldComponentUpdate()
는 컴포넌트를 업데이트 해야될 지 안해도 될 지를 물어보는 함수이다. 컴포넌트의 이전 props와 state를 얕게 비교해 그 결과에 따라 true
, false
를 리턴한다.
❗ 일반 Component인 경우, 따로 Lifecycle methods중 하나인
shouldComponentUpdate
를 구현하지 않았다면,setState
가 호출 될 때마다 render 함수가 반드시 호출된다.
const cart1 = { name: 'lemon' };
const cart2 = cart1;
1. cart1 == cart2 // true
2. ShouldComponentUpdate // false
둘의 참조값이 같으므로, 업데이트 할 필요가 없어서 ShouldComponentUpdate
함수는 false
를 리턴
( 이때, 동일한 값을 가지고 있더라도, 둘은 엄연히 다른 오브젝트이므로 다른 참조값을 가지게 됨 )
const cart1 = { name: 'lemon' };
const cart2 = { name: 'lemon' };
1. cart1 == cart2 // false
2. ShouldComponentUpdate // true
둘의 참조값이 다르므로, 업데이트가 필요하다. 즉ShouldComponentUpdate
함수는 true
를 리턴하게 된다.