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 를 사용해보니 어떤가요? 꽤나 쓸만하지요?

results matching ""

    No results matching ""