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.7 KiB

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

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

JavaScript에서 불변성의 데이터를 다루는 것은 Clojure같이 그것을 위해 디자인된 언어로 다루는 것보다는 어렵습니다. 하지만, React는 간단한 불변성 헬퍼를 제공합니다. update()는 이런 종류의 데이터를 근본적인 변화 없이 쉽게 다루도록 해줍니다. Immutable-js에 관한 좀 더 자세한 정보는 페이스북의 Immutable-js성능 심화을 참조하세요.

주요 아이디어

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

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}