Don’t worry about failures

불변성 본문

React

불변성

허흥 2021. 5. 8. 16:03
728x90

처음 리액트를 접하면서, 가장 당황했던 부분이 리렌더링이다.

 

변수를 새롭게 할당해줄 때마다 해당 컴포넌트가 리렌더링되고, 상태관리를 제대로 못해주게되면 모든 컴포넌트가 리렌더링이 발생되는 상황이 생길 수 있다.

 

angular와 다른 경험이라 매우 당황했다. 상태를 수정할 때 이러한 경험을 하지 못했기 때문에 더욱 크게 다가왔다.

 

이 생각은 많은 사람들이 다루었고, 불필요한 곳에서 리렌더링이 발생되지 않도록, 최적화를 많이 시킨다고한다. 이를 더해 불변성을 유지해주고, 최적화를 도와주는 라이브러리를 도입하여 개발의 편의를 더해주고 있다.

ex) immer, immutable

(앵귤러에서도 사실 이런 이슈가 있을 수도 있지만, 내가 모르는 것일수도,,)

 

그렇담 왜 불변성을 추구하고자할까

우선 이에 앞서 자바스크립트의 데이터 할당이 어떻게 되는지 파악해야한다.

 

변수는 콜스텍과 힙메모리에 저장이되며, 종류에는 원시변수와 참조변수가 존재한다.

 

원시변수 - 콜스텍에 값과 함께 저장.

참조변수 - 힙메모리에 값이 저장되고, 콜스텍에는 힙메모리의 주소가 저장이된다.

 

여기서 불변성의 개념을 다시 살펴보자. 불변성에서 의미하는 것은 힙메모리의 값이 변하지 않는다라는 의미로 생각하면된다.

리액트가 이러한 불변성을 지키고자하는 이유는 리액트의 상태비교를 앝은 비교를 통해 이루어지기 때문이다.

 

얕은 비교란 콜스텍에 있는 주소값을 비교하는 것이고,

깊은 비교란 힙메모리의 값을 비교하는 것이다.

 

리액트는 더 빠르게 값을 비교하고자 얕은 비교를 택하여 리렌더링이 되는 조건을 정한 것이다.

즉, 불변성을 지켜줘야 값을 비교하여 리렌더링을 발생시킬 수 있는 것이다.

 

간단한 예시로 봐보자.

불변성을 지키지 않는 메소드인 push를 봐보자.

const a = [1,2,3];

a.push(4);

이와 같이 푸쉬를 하게된다면 콜스텍 값을 변하지않고, 힙메모리만 변하게된다. 이렇게되면 리액트 입장에서는 콜스텍에 있는 주소값만 비교해서 리렌더링을 할지말지 결정하기 떄문에 결과적으로는 리렌더링이 발생되지않는다.

 

이러한 이유 때문에 새로운 배열을 리턴해주는 메소드를 사용하여 setState를 해줘야한다.

예) es5 - slice, map, filter, reduce, es6 - spread operater, es2023 - toReversed(), toSorted(), toSpliced(), with()

 

불변성 유지되지 않은 메소드

ex) splice, sort, reverse, push

 

2차원이상의 참조변수는 어떻게해야할까?

JSON.parse(JSON.stringify())

loadash의 cloneDeep()

DOM API의 structuredClone();

 

728x90

'React' 카테고리의 다른 글

React DOCS Reading study(3)  (0) 2021.06.19
React DOCS Reading study(2)  (0) 2021.06.18
React DOCS Reading study(1 - JSX)  (1) 2021.06.16
Virtual DOM  (1) 2021.05.08
(Intro) 새롭게 react 들어가며,,  (0) 2021.05.08