[React] Immutability 불변성을 지켜야하는 이유?

bbio3o·2021년 3월 9일
0

React

목록 보기
3/5
post-thumbnail

불변성은 어떤 값을 직접적으로 변경하지 않고 새로운 값을 만들어내는 것입니다.
필요한 값을 변형해서 사용하고 싶다면 어떤 값의 사본을 만들어서 사용해야 합니다.

자바스크립트에서 변수에 문자열, 숫자와 같은 원시형 데이터를 할당하게 되면 데이터 자체가 변수에 할당되지만,
오브젝트를 변수에 할당하면 변수에는 오브젝트가 메모리에 들어있는 주소인, 참조값이 할당되어집니다.
객체와 변경불가성 Immutability

const user = { name: 'Lee', age: 5 } 
const copyUser = user; // 배열의 복사가 아니라 같은 참조 값을 가짐 
user.age += 1; 

/* 
user = { name: 'Lee', age: 6 } 
copyUser = { name: 'Lee', age: 6 } 
*/ 

user === copyUser // true


...라는 spread operator를 사용하면 user와 otherUser가 가리키는 객체의 참조 값은 다르게 됩니다.

따라서 user의 값 변경은 otherUser의 객체에 영향을 주지 않습니다. (불변성이 잘 지켜졌다고 할 수 있습니다.)

예시로 어떠한 인쇄물을 프린트하면 똑같은 것이 총 두 장 생기는데 한 장의 인쇄물에 낙서를 해도 다른 인쇄물에 영향을 주지 않는 것과 같습니다.

const user = { name: 'Lee', age: 5 } 
const otherUser = { ...user }
user.name = 'Park'

/* 
user = { name: 'Park', age: 5 } 
otherUser = { name: 'Choi', age: 5 } 
*/ 

user === otherUser // false 서로 다른 참조 값을 가지고 있음

하지만 객체의 깊이가 깊어지면 여전히 문제가 생깁니다.
spread operator는 얕은 복사(shallow copy) 를 하게 되는데 완전히 다른 객체를 만들고 싶다면 깊은 복사(deep copy)를 해야 합니다.

const user = { name: 'Choi', age: 25, friends: ['Park', 'Kim']} 
const otherUser = { ...user }; 
user.name = 'Lee'; 
user.friends.push('Kang'); 

/* 
user = { name: 'Lee', age: 25, friends: ['Park', 'Kim', 'Kang'] } 
otherUser = { name: 'Choi', age: 25, friends: ['Park', 'Kim', 'Kang'] } 
*/ 

user === otherUser // false 
user.friends === otherUser.friends // true


React Component가 리렌더링 되는 조건은 Props, State의 값이 바뀌거나 부모 컴포넌트가 리렌더링될 때가 있습니다.

여기서 React Component의 Props나 State의 값이 바뀔 때 바뀌었는지 안 바뀌었는지 어떻게 확인할까요?

이전 값과 현재 값을 전체적으로 비교한다고 가정해봅시다.

상태 객체가 다음과 같을 때 모든 요소를 하나하나 비교하는 방법은 비효율 적일것입니다.

따라서, React에서는 값을 비교할 때는 얕은 비교를 실행하여 성능 최적화를 만들어내게 됩니다.(PureComponent, shouldComponentUpdate(), React.memo 등을 이용할 때 오브젝트가 참조하고 있는 주소가 같으면 업데이트하지 않아도 된다 생각하고 객체 내부의 값이 새로워져도 바뀐 것을 감지 하지 못합니다.)

그렇기 때문에 불변성을 지켜주는 일이 중요한 것입니다. 내부의 값이 객체 혹은 배열이라면, ...와 같은 스프레드 연산자를 통해 내부의 값 또한 따로 복사해 주어야합니다.

출처

profile
그림도 그리는 개발자 🎨👩‍💻

0개의 댓글