React | React의 state가 불변성을 가져야하는 이유

🚀·2021년 9월 24일
7

react

목록 보기
7/7
post-thumbnail

spread operator를 사용하여 setState하기

리액트에서 state값이 객체인 경우 setState를 통해 상태값을 업데이트 시킬때, spread operator를 사용해서 기존의 state값은 유지시키고 그것을 복사해서 업데이트한 값으로 상태를 바꿔준다. 이는 리액트에서 불변성을 지켜야 하는 이유와 관련이 깊다.

const onChange = (e) => {
    const { name, value } = e.target

    setInputs({
      ...inputs,            // 이 부분 
      [name]: value,        
    })
  }

불변성이란

불변성은 어떤 값을 직접적으로 변경하지 않고 새로운 값을 만들어내는 것이다.

코어자바스크립트 1장 데이터타입에서 살펴보았듯이 원시 타입은 괜찮지만 객체 타입의 불변성을 지키는 것은 고려해야 할 부분이 있다.

코어자바스크립트 1장을 참고하면, 만약 원시타입이 아닌 객체타입의 데이터를 어떠한 변수에 할당하고 그 변수를 다른 변수에 다시 할당했다면, 배열의 복사가 이루어지는 것이 아니라 같은 참조값을 갖게 된다. 그래서 만약 사본을 수정하면 원본도 함께 수정이 되어버린다.

React로 넘어와보자.

React가 화면을 업데이트하는 과정은 다음과 같다.

  1. setState 호출 (혹은 부모로부터 props를 전달 받는다.)
  2. shouldComponentUpdate를 실행했는데 fasle를 리턴하면 여기서 멈추고, true를 리턴하면 다음 단계로 이동.
  3. 가상 DOM과 실제 DOM을 비교해서 변경사항이 있으면 화면을 다시 그린다.

여기서 shouldComponentUpdate는?

  • 각각의 컴포넌트들은 shouldComponentUpdate라는 메소드를 가지고 있고 이것은 state가 변경되거나 부모 컴포넌트로부터 새로운 props를 전달받을 때 실행됩니다. React는 이 메소드(shouldComponentUpdate)의 반환 값에 따라서 re-render를 할지에 대한 여부를 결정하게 됩니다.
  • 기본적으로 shouldComponentUpdate 메소드는 true를 반환합니다. 하지만 React 개발자는 re-render를 원하지 않는 경우에, 이 return value를 false로 오버라이드 할 수 있습니다.

특정 컴포넌트가 업데이트를 할 필요가 없다는 것을 어떻게 판단할 수 있을까? 가장 간단한 방법은 컴포넌트가 갖고 있는 데이터(props, state)의 이전 이후 값을 완전히 비교하는 것이다.

불변성이 지켜지지 않으면 객체 내부의 값이 새로워져도 바뀐것을 감지하지 못한다.

spread operator의 한계

추가로 전개 연산자(spread operator)을 사용하여 객체나 배열 내부의 값을 복사할 때는 얕은 복사를 하게 된다. 즉 내부의 값이 완전히 새로 복사되는 것이 아니라 가장 바깥쪽에 있는 값만 복사된다. 따라서 내부의 값이 객체 혹인 배열이라면 내부의 값 또한 따로 복사해 주어야 한다.

배열 혹은 객체의 구조가 정말 복잡해진다면 이렇게 불변성을 유지하면서 업데이트 하는 것도 까다로워진다. 이렇게 복잡한 상황인 경우 immer라는 라이브러리의 사용으로 편하게 작업이 가능하다.

즉 다음과 같은 이유로, 우리가 state를 바꾸고 돔을 다시 만들려면, 새로운 객체나 배열을 만들어 새로운 참조값을 만들고 react에게 이 값은 이전과 다른 참조값임을 알려야 한다.

따라서 기존의 state값은 변하지 않도록 불변하게 만들고 새롭게 복사한 객체로 업데이트를 시켜 이전과 다른 값임을 알려야 한다.

이렇게 state값을 포함한 변수도 불변성을 갖게 해야 다른 버그나 예외사항이 일어나지 않는다.

immutable variable을 만드는 방법

React에서 immutable variable을 만드는 여러가지 방법이 있다.

  1. 자바스크립트 표준 함수 ES6 Object.assign() 또는 object-rest-spread
  2. 자바스크립트 라이브러리 immutable-js
  3. react공식 문서에서 추천하는 패키지인 immutability-helper

0개의 댓글