개발하는 일상

상태 관리에서 Vue와 React의 차이점과 불변성(Difference of state management between Vue and React) 본문

개발 간단 팁

상태 관리에서 Vue와 React의 차이점과 불변성(Difference of state management between Vue and React)

롯데빙빙바 2020. 11. 22. 20:43

결론

React는 불변성에 기반하여 상태 관리를 하고, Vue는 상태가 변하는 것을 허용합니다.

불변성(immutability)이란?

단어를 말 그대로 풀어 보자면 변하지 않는 속성이 됩니다. 하지만 보통 상태 관리에서 말하는 불변성은 선언한 객체(데이터)가 선언 이후 변하지 않도록 관리하는 방식을 말합니다. 아래 코드를 보세요.

const obj = {
  foo: 'hello world!',
  bar: true,
};
// 불변성 위반!
obj.foo = 'bye world!';

선언한 obj의 내부를 선언 이후에 수정하고 있으므로, 이 코드는 불변성을 위반한 코드입니다.

React의 상태 관리

이미 선언한 객체가 변해서는 안 된다니, 그럼 대체 상태가 변해야 할 때는 어떻게 해야 된다는 말인 걸까요? React Hooks를 이용해 예를 들어 보겠습니다.

// ...
function App(){
  const [obj, setObj] = useState({
    foo: 'hello world!',
    bar: true,
  });

  // ...
  const onClick = () => {
    // 불변성 위반!
    // obj.foo = 'bye world!'

    // 올바른 방법
    setObj({
      ...obj,
      foo: 'bye world!,
    });
  }
  // ...
}

위의 코드에서

  1. setObj가 실행되면 App이 다시 실행됩니다.
  2. 다시 실행될 때 새롭게 선언되는 obj에는 이전에 setObj에 인자로 넘겨준 새로운 객체가 할당되게 됩니다.

즉, 처음에 선언한 obj는 변경되지 않고 그대로 남아있게 되는 것이죠. React에서 상태의 변경이 필요할 때는 이런식으로 해당 객체를 직접 수정하지 않고(불변성), 수정이 필요한 내용을 포함한 새로운 객체를 만들어 관리하게 됩니다.

왜 이렇게 하는 걸까요?

이렇게 번거로운 작업을 하는 이유는 성능에 있습니다. React는(물론 Vue도) 상태가 변경되면 DOM에 다시 이를 그리는 일을 합니다. 그러면 상태가 변했다는 것을 알아차려야 하는데, 이 변화를 알아차리는 것이 불변성을 지켜줬을 때 훨씬 쉬운 작업이 됩니다.
아래의 코드를 보시죠.

const obj = { foo: 'hello world! };
const obj2 = { foo: 'hello world! };
obj === obj2 // false

만약 불변성이 지켜졌을 경우, 위와 같은 비교를 하게 되는데, 이 비교는 객체의 주소값 자체가 다르므로 쉬운 연산입니다. 만약 불변성을 지키지 않는다면, 객체 내부를 모두 들여다 보며 이전 상태와 비교를 해야 상태의 변화를 알아차릴 수 있고, 불변성을 지켰을 경우 보다 훨씬 어려운 연산을 하게됩니다.

Vue의 상태관리

그렇다면 Vue에서도 똑같이 불변성을 지켜 상태관리를 해야하는 걸까요? 그렇지 않습니다. Vue에서는 data로 관리되는 객체의 속성을 직접적으로 변경하는 것을 허용합니다. 위에서는 그렇게 할 경우에 변화를 알아차리는 비용이 많이 발생한다고 했었는데, Vue는 어떻게 그 문제를 해결했을까요?
Vue의 공식문서에 소개된 Vue의 반응성이 동작하는 구조를 살펴보면, 다음과 같은 말이 있습니다.

Vue 인스턴스에 JavaScript 객체를 data 옵션으로 전달하면 Vue는 모든 속성에 Object.defineProperty를 사용하여 getter/setters로 변환합니다.

js의 객체에는 getter/setter 속성이 있습니다(mdn문서). Vue에서 data로 object를 관리하게 되면 모든 내부 속성에 대해서 getter/setter를 달아두는데요. 이 getter/setter에서 데이터의 변경이 일어날 때 Vue에 알리는 기능을 수행한다고 합니다.

마무리

저는 React와 Redux를 먼저 사용하며 반드시 상태관리를 할 때 불변성은 무조건 지켜야한다는 생각을 가졌었습니다. 하지만 Vue를 알게되며 불변성을 꼭 지키지 않아도 문제를 해결할 수 있는 방법은 있다는 것을 알게 되었습니다. 무조건 하나의 방법보다 방법은 다양하다는 생각을 가져야겠다는 생각을 하며 글을 마칩니다.

Comments