React

Redux-actions

규몽 2020. 12. 2. 00:14

redux-actions을 사용하면 더 편하게 액션 생성 함수를 더 짧게 작성할 수 있다. 그리고 리듀서를 작성할 때도 switch/case 문이 아닌 handleActions라는 함수를 사용해서 각 액션마다 업데이트 함수를 설정 해줄 수 있다.

(이거 없으면 action하고 reducer 생성 버벅이는건 비밀...)

 

우선 라이브러리를 깔아준다.

yarn add redux-actions

CreateAction

그럼이제 이런 액션을

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

 

요렇게 간단하게 가능하다!

export const increase =createAction(INCREMENT,index=>index);
export const decrease =createAction(DECREMENT,index=>index);

 

createAction으로 액션을 만들면 액션에 필요한 추가 데이터는 payload라는 이름을 사용한다.

액션 생성 함수에서 받아온 파라미터를 그대로 payload에 넣는게 아니라 변형을 줘서 넣고 싶다면

createAction 함수 두 번째 인자에 payload를 정의하는 함수를 따로 선언해서 넣어주면 된다.

ex) const change = createAction(CHANGE,number=>"number");

 

아참 어떤 파라미터를 받는지 명시하지 않았기 때문에 헷갈릴 수도 있다!

그러기에 createAction의 두 번째 파라미터에 payload  생성 함수를 전달하여 코드상으로 명시해 줄 수도 있다.


handleActions 

 

handleActions를 사용하면 기존 switch/case 문을 대체하여 더 간단하고 가독성 높게 작성 할 수 있다.

 

요거를

fuction counter(state,action){
 switch(action.type){
 	case INCREASE:
    	return{
        	number:state.number+1
          };
    case DECREASE:
    	retrun{
        	number:state.number-1
          };
        default:
        	return state;
    }
}

 

요렇게 개꿀 ㅇㅈ?

handleActions 함수의 첫 번째 파라미터에는 각 액션에 대한 업데이트 함수를 넣고 두 번째 파라미터엔 초기값(init객체)를 넣어 주면 된다.

 

const counter = handleActions({
	[INCREASE]:(state,action)=>({number:state.number+1}),
 	[DECREASE]:(state,action)=>({number:state.number-1}),
  },init);

 

createAction으로 만든 액션 생성 함수는 파라미터로 받아 온 값을 객체 안에 넣을 때 원하는 이름으로 넣는 것이 아니라 action.id, action.todo와 같이 action.payload라는 이름을 공통적으로 넣어주게 된다. 그렇기 때문에 기존의 업데이트 로직에서도 모두 action.payload라는 값을 조회해서 업데이트 해줘야 된다.

 

액셩 생성 함수는 액션에 필요한 추가 데이터를 모두 payload라는 이름으로 사용하기 때문에

action.id, action.todo를 조회하는 대신 모두 공통적으로 action.payload 값을 조회하도록 리듀서에서 구현해줘야 된다.

 

근데 이럼 모든 추가 데이터 값이 action.payload로 사용하기 때문에 나중에 리듀서 코드를 다시 볼 때 햇갈릴수 있다.

객체 비구조화 할당 문법으로 action 값의 payload 이름을 새로 설정해주면 action.payload가 어떤 의미인지 쉽게 파악 가능하다.

 

ex) const todos = handleActions({ [INSERT]: (state,{payload:todo}) => ({ ...state,todos:state.todos.concat(todo) }) },init );

 

immer은 아직 확실히 안써봣으므로 다음 시간에... ㅋㅋ