immutable.js 대신 immer 사용해보기!
immer 에 대해선 https://react-etc.vlpt.us/02.immer.html 를 확인하세요!
설치
프로젝트 디렉토리에서 다음 명령어를 통하여 immer 를 설치하세요.
yarn add immer
그 다음에, 우리가 만들었던 리덕스 모듈들을 새로 작성해주겠습니다.
src/store/modules/counter.js
import { createAction, handleActions } from 'redux-actions';
import produce from 'immer';
// 액션 타입을 정의해줍니다.
const INCREMENT = 'counter/INCREMENT';
const DECREMENT = 'counter/DECREMENT';
// 액션 생성 함수를 만듭니다.
export const increment = createAction(INCREMENT);
export const decrement = createAction(DECREMENT);
// 모듈의 초기 상태를 정의합니다.
const initialState = {
number: 0
};
// :: immer 를 사용하여 값을 수정하는 리듀서입니다.
export default handleActions({
[INCREMENT]: (state, action) => {
return produce(state, draft => {
draft.number++;
});
},
// :: { } 를 따로 열지 않고 바로 리턴하면 이런 형식입니다.
[DECREMENT]: (state, action) => produce(state, draft => {
draft.number--;
}),
}, initialState);
여기는 꽤 간단하죠?
src/store/modules/todo.js
todo 모듈 또한 꽤 명료하게 수정해줄 수 있습니다.
import { createAction, handleActions } from 'redux-actions';
import produce from 'immer';
const CHANGE_INPUT = 'todo/CHANGE_INPUT';
const INSERT = 'todo/INSERT';
const TOGGLE = 'todo/TOGGLE';
const REMOVE = 'todo/REMOVE';
let id = 0;
export const changeInput = createAction(CHANGE_INPUT, value => value);
export const insert = createAction(INSERT, text => ({
text,
id: id++
}));
export const toggle = createAction(TOGGLE, id => id);
export const remove = createAction(REMOVE, id => id);
const initialState = {
input: '',
todos: []
};
export default handleActions(
{
[CHANGE_INPUT]: (state, action) =>
produce(state, draft => {
draft.input = action.payload;
}),
[INSERT]: (state, { payload: { id, text } }) => {
const item = {
id,
text,
checked: false
};
return produce(state, draft => {
draft.todos.push(item);
});
},
[TOGGLE]: (state, { payload: id }) => {
// 인덱스 가져와서
const index = state.todos.findIndex(item => item.id === id);
return produce(state, draft => {
// 그냥 반전시키기!
draft.todos[index].checked = !draft.todos[index].checked;
});
},
[REMOVE]: (state, { payload: id }) => {
// id 값을 가진 index 를 찾아서 지웁니다.
const index = state.todos.findIndex(item => item.id === id);
return produce(state, draft => {
draft.todos.splice(index, 1); // 지울때는 splice 를 사용합니다.
});
}
},
initialState
);
이렇게 작성해주고 나면, 우리가 6편에서 이미 Record 를 사용시도 해보면서 컨테이너쪽에서 .get 을 쓰지 않도록 수정해주었기 때문에, 이 두 모듈 말고는 따로 수정 할 파일이 없습니다.
immer 를 사용해보니 어떤가요? 꽤나 쓸만하지요?