3.1 Map
Immutable의 Map
은 객체 대신 사용되는 데이터 구조입니다. 이는 JavaScript 에 내장되어있는 Map 과는 다릅니다.
실습 준비
Immutable을 리액트 프로젝트에 설치해서 사용해보기 전에, 먼저 JSBin 에서 CDN을 통하여 불러온 후 간단한 사용법을 먼저 익혀보도록 하겠습니다.
http://jsbin.com/ 에 들어가서, 상단의 Add Library 를 눌러 Immutable 을 추가하세요 (하단부에 있습니다.)
Immutable을 추가하고 나면 html 섹션에 다음 코드가 추가됩니다
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.3/immutable.min.js"></script>
그 다음엔, 상단의 버튼들을 눌러 JavaScript / Console 을 제외한 섹션들을 숨기세요.
사용해보기
한번 Map 을 생성해보도록 하겠습니다.
var Map = Immutable.Map;
var data = Map({
a: 1,
b: 2
})
위와 같이, Map()
함수 안에 객체를 넣어서 호출하면됩니다.
이번엔, 여러 층으로 구성된 객체를 Map으로 만들어보겠습니다.
var Map = Immutable.Map;
var data = Map({
a: 1,
b: 2,
c: Map({
d: 3,
e: 4,
f: 5
})
})
위와 같이, 객체 내부에있는 객체들도 Map
으로 감싸주어야 합니다.
혹은, 다음과 같이 fromJS
를 사용해도 됩니다.
var fromJS = Immutable.fromJS;
var data = fromJS({
a: 1,
b: 2,
c: {
d: 3,
e: 4,
f: 5
}
})
fromJS
는 내부의 객체들도 Map
으로 변환해줍니다.
자, 이렇게 만든 Map 을 한번 콘솔로 프린트해보세요.
코드를 입력 후 우측 상단의 Run 을 눌러야 실행됩니다.
Map을 그대로 프린트 할 수는 없습니다.
이런것도 할 수 없습니다.
console.log(data.a);
// undefined
Map 으로 만든건 일반 객체가 아니므로 다른 방법으로 다뤄줘야 합니다.
자바스크립트 객체로 변환하기
우선, Map 을 일반 객체로 변형하는 방법은 다음과 같습니다:
data.toJS(); // { a:1, b:2, c: { d: 3, e: 4 } }
toJS()
함수는 Map 을 일반 자바스크립트 객체형태로 변화시켜줍니다.
특정 키의 값 불러오기
그리고, Map 의 특정 키의 값을 불러올땐, 다음과 같습니다:
data.get('a'); // 1
get()
함수는 파라미터로 전달된 key 의 값을 가져옵니다.
깊숙한 값 불러오기
더욱 깊숙히 들어있는 값을 가져와야 할땐 다음과 같이합니다:
data.getIn(['c', 'd']) // 3
값 설정하기
값을 설정할때에는 get
대신에 set
을 사용하면 됩니다.
var newData = data.set('a', 4);
주의: set을 한다고해서, data가 변하는게 아닙니다. 주어진 변화를 적용한 새 Map을 만듭니다.
깊숙한 값 설정하기
깊숙히 들어있는 값을 설정해야할땐 setIn
을 사용하면 됩니다:
var newData = data.setIn(['c', 'd'], 10);
여러개의 값 설정하기
여러개의 값을 동시에 설정 할 때에는 mergeIn
을 사용합니다.
예를 들어서, c.d 와 c.e 의 값을 동시에 바꿔야 하는 경우에는, 다음과 같이 하면 됩니다.
var newData = data.mergeIn(['c'], { d: 10, e: 10 });
이렇게 했을 때, c.f 의 값은 그대로 유지 됩니다.
다음과 같이 해도 좋습니다.
var newData = data.setIn(['c', 'd'], 10);
.setIn(['c', 'e'], 10);
만약에 최상위에서 merge
를 해야 할땐 다음과 같이 합니다:
var newData = data.merge({ a: 10, b: 10 })
set
을 여러번 할 지, 아니면 merge
를 할진는 그때 그때 상황에 맞춰서 하면 되지만, 성능상으로는 set
을 여러번 하는것이 더 빠릅니다.(링크)
전체 객체를 업데이트 해야 하는 경우에는, merge 를 사용하는 것 보단 다음처럼 하는것이 좋습니다.
var newData = data.set('c', Map({ d: 10, e: 10, f: 10 }))