새로 알게 된 것 : 컴포넌트 최적화
React.memo
컴퍼넌트가 React.memo()로 래핑될때 React는 컴퍼넌트를 렌더링하고 결과를 메모이징한다.
그 다음 렌더링의 결과가 이전과 같다면 React는 메모이징 이전 내용을 제시한다.
같은 props로 렌더링이 자주 일어나는 컴퍼넌트 에서는 React.memo를 사용하는 것이 더 좋은 성능을 나타낸다.(불필요한 리렌더링을 줄인다.)
다음을 보자. TodoItem
컴퍼넌트를 다음과 같이 정의한다.
function TodoItem({ todo, onToggle }){
return (
<li
style = {{ textDecoration : todo.done ? 'line-through' : 'none'}}
onClick = {()=> onToggle(todo.id)}
>
{todo.text}
</li>
);
}
위 영상에서 보다시피 기존에 렌더링되어 있던 TodoItem
컴퍼넌트들도 계속 렌더링된다.
이번엔 TodoItem
을 React.memo()
로 래핑하여 사용해보자.
const TodoItem = React.memo(function TodoItem({todo,onToggle}){
return (
<li
style = {{ textDecoration : todo.done ? 'line-through' : 'none'}}
onClick = {()=> onToggle(todo.id)}
>
{todo.text}
</li>
);
}
);
기존에 렌더링된 TodoItem
중 props
가 변경되지 않은 것들은 리렌더링되지 않는다.
이런식으로 React.momo()
를 사용하면 리렌더링 낭비를 줄이면서 성능을 높힐 수 있다.
useSelector
와 equalityFn
상태가 바뀌지 않았을 때 useSelector
를 통해 매번 렌더링하는 것은 낭비렌더링이다.
이를 최적화 하는 방법으로는 두가지 방법이 있다.
useSelector
를 여러번 사용한다.
다음과 같이 useSelector 하나를 통해 객체를 리턴할 때, 객체는 메모리주소를 참조하기 때문에 매번 다른 값으로 인식된다.
const { number, diff } = useSelector(state => ({
number: state.counter.number,
diff: state.counter.diff
}));
즉, 매번 새로운 객체 { number, diff }
를 만든다. 상태가 바뀌었는지 않았는지 확인을 할 수 없어 매번 렌더링이 이루어진다.
반면, 다음과 같이 state 개수만큼 useSelector를 사용하면 해당 값이 바뀌었을 때에만 컴포넌트가 리렌더링 된다.
값을 비교하기 때문에 전,후가 같을때는 리렌더링을 하지 않는다.
const number = useSelector(state => state.counter.number);
const diff = useSelector(state => state.counter.diff);
react-redux
의 shallowEqual
함수를 useSelector
의 두번째 인자로 전달한다.
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
.
.
const { number, diff } = useSelector(
state => ({
number : state.counter.number,
diff : state.counter.diff
}), shallowEqual );
.
.
useSelector
의 두번째 파라미터는 이전값과 다음값을 비교하여 boolean
값을 리턴하는 equalityFn
이다.true
가 나오면 리렌더링을 하지 않고, false
가 나오면 리렌더링을 한다.shallowEqual
은 react-redux
에 내장되어 있는 함수로서, 가장 겉에 있는 "값" 들을 비교한다.
즉, 이전값과 다음값을 비교하여 같다면 true
를 리턴하여 리렌더링을 하지 않고, 다르다면 false
를 리턴하여 리렌더링한다.
'개발 > React' 카테고리의 다른 글
Code Splitting - dynamic import, React.lazy(), Suspense (0) | 2021.11.05 |
---|---|
Virtual Dom, DOM조작횟수를 줄여서 리렌더링을 줄여보자! (0) | 2021.11.04 |
번역)Presentational and Container Components (0) | 2021.09.27 |
Styled-Component에 hover 간단하게 넣는 법 (0) | 2021.09.14 |
리액트 key (0) | 2021.08.20 |