Immutable
setState()
는 객체 깊숙한 곳 까지 확인하지 못하여, 전개 연산자를 사용해야합니다. 이러한 작업은 복잡하므로 immutable.js을 사용합니다.
1. 설치하기
프로젝트에서 Immutable을 사용 할 땐, 다음과 같이 패키지를 설치해서 사용합니다.
npm install --save immutable
2. 사용 규칙
Immutable을 사용할때는 다음 규칙들을 기억해야 합니다.
객체
Map()
을 사용합니다.
const obj = Map({
foo: 1,
inner: Map({
bar: 10,
})
});
배열
List()
를 사용합니다.
const arr = List([
Map({ foo: 1 }),
Map({ bar: 2 }),
]);
설정
set()
을 사용합니다.
const nextObj = obj.set('foo', 5);
읽기
get()
을 사용합니다.
const foo = obj.get('foo');
const value = arr.get(0);
읽은 다음에 설정
update()
를 사용합니다.
cost updateObj = obj.update('foo', value => value + 1);
내부 데이터 접근
getIn()
, setIn()
, updateIn()
을 사용합니다.
const setObj = obj.setIn(['Inner', 'bar'], 20);
const bar = setObj.getIn(['Inner', 'bar']);
const setArr = arr.setIn([0, 'foo'], 10);
const value = setArr.getIn([0, 'foo']);
일반 자바스크립트 객체로 변환
toJS()
를 사용합니다.
const nomalObj = obj.toJS();
const nomalArr = arr.toJS();
List 내장 함수
push()
, slice()
, filter()
, sort()
, concat()
과 같이 배열 내장함수와 비슷한 함수가 있습니다.
const pushArr = arr.push(Map({ qaz: 3 }));
const filterArr = arr.filter(item => item.get('foo') === 1);
삭제
Map
에서 특정 key를 지우거나 List
의 원소를 지울 떄는 delete()
를 사용합니다.
const deleteObj = obj.delete('foo');
const deleteArr = arr.delete(0);
3. 리액트 컴포넌트에서 사용하기
Immutable은 페이스북에서 만들었기 때문에 React와 호환이 되긴 하지만, state
자체를 immutable로 사용할 수는 없습니다.
state 만들기
this.state = {
data: Map({
input: '',
users: List([
Map({
id: 1,
username: 'user01',
}),
Map({
id: 2,
username: 'user02',
}),
]),
}),
};
state 수정하기
onChnage = event => {
const { value } = event.target;
const { data } = this.state;
this.setState({
data: data.set('input', value),
});
}
onButtonClick = () => {
const { data } = this.state;
const { id } = this;
this.setState({
data: data.set('input', '')
.update('users', users => users.push(Map({
id: id + 1,
username: data.get('input'),
}))),
});
}
state 사용하기
render() {
const { onChange, onButtonClick } = this;
const { data } = this.state;
const input = data.get('input');
const users = data.get('users');
return (
<div>
<div>
<input onChange={onChange} value={input} />
<button type="button" onClick={onVuttonClick}>
추가
</button>
</div>
<h1>사용자 목록</h1>
<div>
<UserList users={users} />
</div>
</div>
)
}
4. Record 사용하기
Record를 사용하면 Immutable의 set()
, update()
, delete()
등을 계속 사용 할 수 있으면서, 값을 조회할 때 get()
, getIn()
을 사용하지 않고 data.input
과 같이 직접 조회할 수 있습니다.
const Person = Record({
name: '홍길동',
age: 1,
});
const user01 = Person();
// { name: "홍길동", age: 1 }
const user02 = Person({
name: '영희',
age: 10,
});
// { name: "영희", age: 10 }
const nested = Record({
foo: Record({
bar: true,
})(),
})();
// nested.foo.bar === true
const nextNested = nested.setIn(['foo', 'bar'], false);
// nextNested.foo.bar === false