You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

4.5 KiB

id title permalink prev next
update-ko-KR 불변성 헬퍼들 update-ko-KR.html clone-with-props-ko-KR.html pure-render-mixin-ko-KR.html

React에서는 mutation을 포함해 어떤 데이터 관리 방식도 사용하실 수 있습니다. 하지만 애플리케이션의 성능이 중요한 부분에서 불변의(immutable) 데이터를 사용할 수 있다면, 쉽게 빠른 shouldComponentUpdate() 메소드를 구현해 애플리케이션의 속도를 크게 향상시킬 수 있습니다.

JavaScript에서 불변성의 데이터를 다루는 것은 Clojure같이 그것을 위해 디자인된 언어로 다루는 것보다는 어렵습니다. 하지만, React는 간단한 불변성 헬퍼를 제공합니다. update()는 이런 종류의 데이터를 근본적인 변화 없이 쉽게 다루도록 해줍니다.

주요 아이디어

만약 데이터를 이렇게 변화시킨다면:

myData.x.y.z = 7;
// or...
myData.a.b.push(9);

이전의 카피가 덮어씌워진다면 어떤 자료가 바뀌었는지 알 방도가 없습니다. 대신에, myData의 새로운 카피를 만들고 오직 변화가 필요한 부분만 바꿀 필요가 있습니다. 그 다음 shouldComponentUpdate() 에서 myData의 이전 카피와 새로운 카피를 === 연산자를 사용하여 비교할 수 있습니다.

var newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);

하지만 깊은 복사는 비싸고, 가끔은 불가능하기도 합니다. 변화가 필요한 객체만 복제하고, 변화가 없는 객체는 다시 사용하는 방법으로만 비용을 줄일 수 있습니다. 안타깝지만 오늘날의 JavaScript에서는 그 방법이 성가실 수 있습니다:

var newData = extend(myData, {
  x: extend(myData.x, {
    y: extend(myData.x.y, {z: 7}),
  }),
  a: extend(myData.a, {b: myData.a.b.concat(9)})
});

이것은 꽤 성능이 좋긴 하지만 (log n개의 객체만 얕은 복사하고, 나머지는 재사용하기 때문에), 일일히 쓰기엔 큰 고통이 따릅니다. 이 반복들을 보세요! 이건 짜증날 뿐만 아니라 버그들을 야기할수도 있습니다.

update()는 이런 패턴 속에서 코드를 더 쉽게 쓸 수 있도록 편의 문법을 제공합니다. 코드는 이렇습니다:

var newData = React.addons.update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});

(MongoDB 쿼리 언어에서 영감을 받은) 이 문법에 익숙해지기에는 시간이 조금 걸리긴 하지만, 쓸모 없는 반복이 없고 정적분석이 가능할 뿐더러 변할 수 있는(mutative) 버전보다 더 많은 타이핑이 필요하지도 않습니다.

$가 앞에 붙어있는 키들은 커맨드 라고 불립니다. "변하는" 자료 구조는 타겟 이라고 불립니다.

사용가능한 커맨드들

  • {$push: array} 모든 아이템들을 타겟에 있는 arraypush()합니다.
  • {$unshift: array} 타겟속 array에 있는 모든 아이템들을 unshift()합니다.
  • {$splice: array of arrays} arrays 안의 각 아이템들이 splice()를 주어진 인자들을 사용해 호출하게 합니다.
  • {$set: any} 타겟 전체를 대체합니다.
  • {$merge: object} 타겟과 object의 키들을 병합합니다.
  • {$apply: function} 는 지금 값을 함수에 전달하고 새로운 리턴 값으로 업데이트합니다.

예제

간단한 push

var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]

initialArray 은 여전히 [1, 2, 3] 입니다.

중첩된 컬렉션

var collection = [1, 2, {a: [12, 17, 15]}];
var newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// => [1, 2, {a: [12, 13, 14, 15]}]

이것은 collection의 인덱스 2의 키 a에 접근해, 인덱스 1에 있는 한 아이템을 접합(splice)해서(17를 제거하고) 13, 14를 추가합니다.

현재 상태에 의거해 값을 업데이트

var obj = {a: 5, b: 3};
var newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
// => {a: 5, b: 6}
// 위의 것과 같은 동작을 합니다만, 깊게 중첩된 컬렉션들에서는 더 장황해 집니다.
var newObj2 = update(obj, {b: {$set: obj.b * 2}});

(얕은) 합병

var obj = {a: 5, b: 3};
var newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}