4-2. redux-actions 를 통한 더 쉬운 액션관리

redux-actions 패키지에는 리덕스의 액션들을 관리하기 위한 유용한 createActionhandleActions 가 있습니다. 이번 섹션에서는 이 함수들이 어떤 기능을하는지 알아보도록 하겠습니다.

createAction 을 통한 액션생성 자동화

리덕스에서, 액션을 만들다보면 드는 의문이, 이걸 굳이 하나하나 액션 생성자를 만들어야하나? 입니다.

예를 들어, 우리가 기존에 만들었던 incrementdecrement 코드를 다시 한번 읽어봅시다.

export const increment = (index) => ({
    type: types.INCREMENT,
    index
});

export const decrement = (index) => ({
    type: types.DECREMENT,
    index
});

그냥 파라미터로 전달받은 값을 객체에 넣어주는것 뿐인데 이걸 자동화할수도 있지 않을까요?

createAction을 사용한다면 위 작업을 다음과 같이 자동화 시켜 줄 수 있습니다.

export const increment = createAction(types.INCREMENT);
export const decrement = createAction(types.DECREMENT);

하지만, 이런식으로 하면 그 파라미터의 값이 index 가 될 지 뭐가 될 지 모릅니다. 그렇기 때문에, 파라미터로 전달받은 값을 액션의 payload 값으로 설정해줍니다. 따라서 increment(3) 가 실행된다면, 다음과 같이 객체를 만들어주겠죠.

{
    type: 'INCREMENT',
    payload: 5
}

setColor의 경우엔 어떨까요?

export const setColor = createAction(types.SET_COLOR);
setColor({index: 5, color: '#fff'})
/* 결과:
{
    type: 'SET_COLOR',
    payload: {
        index: 5,
        color: '#fff'
    }
}
*/

어때요? 이해가 가나요? 액션이 갖고있을 수 있는 변수를 payload 로 통일하므로서, 액션을 생성하는것을 자동화 할 수 있게 되는 것이지요. 편리하지만, 단점으로는 코드를 봤을때 해당 액션생성자가 파라미터로 필요한 값이 뭔지 모르기때문에, 그 위에 주석을 작성해주어야 합니다.

switch 문 대신 handleActions 사용하기

리듀서에서 액션의 type 에 따라 다른 작업을 하기 위해서 우리는 switch문을 사용했지요. 하지만 이 방식엔 아주 중요한 결점이 한가지 있습니다. 바로, scope가 리듀서 함수로 설정되어있다는것이지요.

그렇기 때문에 서로 다른 case 에서 let 이나 const 를 통하여 변수를 선언하려고 하다보면 같은 이름이 중첩될시엔 에러가 발생합니다.

그렇다고해서 각 case 마다 함수를 정의하는건 코드를 읽기 힘들어질것이구요..

이 문제를 해결해주는것이 바로 handleActions 입니다. 이 함수를 사용하면 다음과 같은 방식으로 해결 할 수 있습니다.

const reducer = handleActions({
  INCREMENT: (state, action) => ({
    counter: state.counter + action.payload
  }),

  DECREMENT: (state, action) => ({
    counter: state.counter - action.payload
  })
}, { counter: 0 });

첫번째 파라미터로는 액션에 따라 실행 할 함수들을 가지고있는 객체, 두번째 파라미터로는 상태의 기본 값 (initialState) 를 넣어주면 됩니다.

한번, 직접 사용해보고싶지 않나요? 이제, 방금 배운 Duck 구조와 redux-actions 을 저희 카운터에 적용을 해보겠습니다.

results matching ""

    No results matching ""