리액트의 불변성이란? 왜 필요한데?

김민성·2022년 6월 21일
0

immutable : 변경 불가성

immutable은 함수형 프로그래밍의 핵심원리중 하나이다. 객체가 생성된 이후 변할수 없다는 것을 뜻한다.
리액트의 state는 immutable하다고한다, 그런데 state 자체가 동적으로 변하는것 아닌가?? 불변성에 대해 알아보자

불변성이란?

상태를 변경하지 않는것을 의미한다. 아래의 2가지 경우를 살펴보자

1. 원시타입(string,number...)

원시타입은 불변성을 가지고 있다.

let string = "hello"
string ="bye"

위의 경우 string은 bye로 바뀔것이다. 아 그럼 불변성이 깨진것 아닌가? 라고 생각할 수 있다.
하지만 메모리내에 hello, bye 둘다 남아있다. "bye"라는 새로운 값을 참조할 뿐이다. 참조 카운팅이 0이된 hello는 GC의 대상이 되어 메모리에서 사라지게 되겠다.

2. 참조타입(array, object..)

배열의 push 메소드는 원본 데이터를 수정한다. 이로서 불변성을 지켜주지 않은것이 되고, 새로운 배열 [1,2,3,4]를 할당해 새로운 참조값을 만들어 불변성을 지켜준것이 된다.

let array = [1, 2, 3, 4] // 메모리영역 1
array.push(5) // 메모리영역 1 

array = [1, 2, 3, 4]

불변의 진짜 의미는 메모리영역에서 값을 변경할 수 없다는 의미이다.

리액트에서 불변성을 지켜야 하는 이유?

1. 효율적인 상태업데이트(얕은비교)

리액트는 얕은 비교를 통해 상태업데이트를 한다. 얕은 비교란 객체의 프로퍼티를 비교하지않고 참고 주소값을 비교하여 변경을 확인한다.
얕은 비교는 계산리소스를 줄여주므로 효율적인 상태업데이트를 할 수 있다.

2. side-Effect 방지, 프로그래밍 구조의 단순성

원시타입은 애초에 불변성이니 상관없으나, 참조타입인 객체,배열의 경우 원본데이터를 변경할 경우 원본데이터를 참조하는 다른 객체에서 예상치 못한 오류가 생길수 있다.

정리

리액트는 얕은비교를 하기 때문에 만약 push 메소드를 이용해서 원본 배열을 바꾸게 되면 참조값은 그대로 이므로 리액트는 변경되지 않았다고 생각한다.
즉, state를 변경하고 dom을 변경하려면, 새로운 객체 or 배열을 만들어 새로운 참조값을 만들고 react에게 변경사항을 알려야 한다.

참조타입은 의도적으로 불변성을 지켜주어야한다

불변성 지키면서 state변경하기

1. 배열에 추가하기

setUsers(state.array.concat(user))

2. 배열에서 삭제

const onRemove = id => {
  // user.id가 id인것을 제거
  setUsers(users.filter(user => user.id != id))
}
  

3. 배열에서 수정

cosnt onToggle = id => {
 setUsers(
   users.map(user => user.id === id ? {...user, active: !user.active } : user))  
}

4. 객체에서 추가

setState(state => {...state, key:value})

5. 객체에서 수정

setState(state => {...state, ket: newValue})

정리

  1. React 는 얕은 비교(참조 주소값 비교)를 한다
  2. 객체는 의도적으로 불변성을 지켜주자

참조 블로그
https://kyounghwan01.github.io/blog/React/immer-js/#%E1%84%87%E1%85%AE%E1%86%AF%E1%84%87%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A5%E1%86%BC-%E1%84%8C%E1%85%B5%E1%84%8F%E1%85%B5%E1%84%86%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A5-state-%E1%84%87%E1%85%A1%E1%84%81%E1%85%AE%E1%84%80%E1%85%B5
https://kyounghwan01.github.io/blog/React/immer-js/#%E1%84%87%E1%85%AE%E1%86%AF%E1%84%87%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A5%E1%86%BC-%E1%84%8C%E1%85%B5%E1%84%8F%E1%85%B5%E1%84%86%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A5-state-%E1%84%87%E1%85%A1%E1%84%81%E1%85%AE%E1%84%80%E1%85%B5

profile
다양한 경험의 개발자를 꿈꾼다

0개의 댓글