React 에서의 불변성

1
post-thumbnail

🎀 우선 깊은 복사 , 얕은 복사를 알아야한다

자바스크립트에는 원시 타입과 참조 타입이 존재한다.

  • 원시 타입 : Number, String, Boolean, Symbol, Null, Undefined

  • 참조 타입 : Object

  • 깊은 복사 : 기존 값의 주소가 같이 복사되는 것이 아니라 내용만 빼와서 복사된다. 깊은 복사된 값이 변경되어도 기존 값은 변경되지 않고 주소도 새로 생성된다.

  • 얕은 복사 : 기존 값의 주소를 같이 복사해온다. 얕은 복사된 값이 변경되면 기존 값도 같이 변경된다. 🤓🤓

자세한 설명은 여기(JS 얕은 복사 깊은 복사 포스팅)서 확인해 보세요.

🎀 불변성? 가변성?

📌 원시 타입

  • 콜스택에 주소 값과 함께 저장된다
  • 값이 변경 되면 콜스텍에 새로운 값과 주소가 같이 할당되어진다.
  • 메모리 힙에는 아무런 변화가 없다 👉🏻 불변성!!

📌 참조 타입

  • 메모리 힙에 값이 담긴다.
  • 콜 스택에 메모리를 가리키는 주소가 할당된다.
  • 값이 변경되면 메모리 힙의 값이 변경된다 👉🏻 가변성!!

🎀 리액트는?

리액트는 state 값의 변경이 감지되면 렌더링을 시켜주는데,
주소 값이 변경되었는지만 체크하면 효율적이라는 이유 때문에 얕은 비교를 채택하고 있다.

이때, 원시값의 경우 값이 변경되면 참조한 주소가 아예 변경되니까, 감지되기 쉽다.
하지만 참조값의 경우 같은 주소를 참조하여 복사되니까, 감지되지 않을 위험이 높다.

그래서 리액트에서는 참조값을 불변하게 만들어 주어야 하는 것이다.

불변성을 지키기 위해 우리가 사용해야하는 것은 스프레드 연산자이다.
참조값을 아예 다른 값으로 변경시켜주어 주소값도 변경해 주는 것이다.

실제로 리스트를 받아오는 배열에 대한 상태를 업데이트할 때
아래 코드와 같이 스프레드 연산자를 사용하는 이유가 여기에 있는 것이다.

setSelectedTagInfo((prevSelectedTagInfo) => ({
  ...prevSelectedTagInfo,
  ...newSelectedTagInfo,
}));

이 외에
map, filter, slice, reduce 사용 가능하다.
하지만 splice, push는 원본 값을 수정하기 때문에 사용을 지양해야한다.

❗️변경해야하는 참조값이 2 depth 이상일때는 lodash 라이브러리를 사용하자.

❗️원시값은 이렇게해줄 필요가 당연히 없음



📚 압도적 감사 (참고 자료)
라잇의 불변성

profile
일단 해. 그리고 잘 되면 잘 된 거, 잘 못되면 그냥 해본 거!

0개의 댓글