똑같은 삽질은 2번 하지 말자
[vuex] do not mutate vuex store state outside mutation handlers. (feat. javascript의 얕은복사 깊은복사) 본문
[vuex] do not mutate vuex store state outside mutation handlers. (feat. javascript의 얕은복사 깊은복사)
곽빵 2021. 11. 20. 19:08원인
해당에러는 store의 state의 값들을 vuex의 mutation을 통해서가 아닌 직접 값을 변형하려고 할 때 발생하는 에러이다.
ex) this.$store.state.name = gwak;
해결방법
store에서 땡겨온 값들은 기본적으로 복사해서 사용하는게 좋다.
(아니면 값을 변형하는 처리 자체를 하나하나 mutations을 통해 해주거나)
javascript 객체를 복사하는 방법으로써는 두가지의 종류가 있다.
얕은복사(객체안의 객체같은 depth >= 2 인 경우에는 해결방법이 아님)
객체를 복사하지만 객체의 값들중에 원본객체를 참조하고 있는 요소가 존재하면 그건 얕은복사 이다.
1. 객체를 통째로 집어넣기
const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true
2. Object.assign으로 객체를 생성해서 복사했지만, 여전히 안의 요소들은 원본객체를 참조중
const obj1 = {
a: 1,
b: {
c: 2,
},
};
const obj2 = Object.assign({}, obj1);
obj2.b.c = 3
obj1 === obj2 // false
obj1.b.c === obj2.b.c // true
3. 전개 연산자 (spread operator)를 이용한 복사..를 했지만 여전히 내부 객체에선 원본 객체를 참조
const obj1 = {
a: 1,
b: {
c: 2,
},
};
const obj2 = {...obj1}
obj2.b.c = 3
obj1 === obj2 // false
obj1.b.c === obj2.b.c // true
깊은복사(완벽하진 않지만...)
1. JSON.parse(JSON.stringify(복사할 대상)) -> 비추천(낮은 퍼포먼스)
const obj1 = {
a: 1,
b: {
c: 2,
},
};
const obj2 = JSON.parse(JSON.stringify(obj1)),
obj2.b.c = 3
obj1 === obj2 // false
obj1.b.c === obj2.b.c // false
2. 재귀함수를 이용한 복사 (깊은복사를 해야하는 상황이라면 추천하는 방식)
const obj1 = {
a: 1,
b: {
c: 2,
},
};
function copy(obj1) {
const obj2 = {};
for (let key in obj1) {
if (typeof obj1[key] === 'object') {
obj2[key] = copy(obj1[key]);
} else {
obj2[key] = obj1[key];
}
}
return obj2;
}
const obj2 = copy(obj1);
obj2.b.c = 3
console.log(obj1.b.c) // 2
객체안의 객체이외에도 참조형 자료형(배열, 맵등등)이 있다면 그 경우에는 좀더 확장해서 개선 가능할 방법인거같다.
3. lodash 라이브러리를 이용(완벽한 복사가 가능)
이건 해본적이 없으므로 다른 기사들을 참조하시길..
깊은복사를 위해 라이브러리까지 써야하는..상황이라면 구조를 바꾸는게 좋겠다.
내 생각
가능하면 깊은복사같은걸 해야만 하는 상황들을 피하는게 좋다는 기사를 봤다.
javascript 구조상 완벽한 복사는 불가능? 이라는 말이다. ( 밑의 글을 참조!! )
depth가 2이상의 데이터를 깊은복사하는 경우가 오지 않도록 잘 설계..하는게 최고인거 같긴하다..
'Vue' 카테고리의 다른 글
Nuxt에서 Vue I18n으로 국제화(다국어) 적용하기 (0) | 2021.12.05 |
---|---|
Vue Props로 Array, Object의 default를 arrow function으로 하는 이유 (1) | 2021.12.04 |
Vuex에 대한 고민 (0) | 2021.11.14 |
vue(vue-cli)에서 component preload prefetch 기능 끄기 (0) | 2021.11.03 |
vue-cli 와 webpack 설정 (0) | 2021.11.03 |